From e94a7b1a7afe102d74f075e76f2674287f2d2153 Mon Sep 17 00:00:00 2001 From: Lars Hamann Date: Mon, 16 Nov 1998 23:40:50 +0000 Subject: [PATCH] new flags : homogeneous; new guints : tab_hborder, tab_vborder; marked Tue Nov 17 00:06:29 1998 Lars Hamann * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; new guints : tab_hborder, tab_vborder; marked tab_border deprecated (struct _GtkNotebookPage): new flags : expand, fill, pack * gtk/gtknotebook.h/c (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous tabs (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border (gtk_notebook_set_tab_hborder): new function. set tab_hborder (gtk_notebook_set_tab_vborder): new function. set tab_vborder (gtk_notebook_query_tab_label): new function. get tab_label widget. (gtk_notebook_set_tab_label): new function. set tab_label widget. (gtk_notebook_set_tab_label_text): new function. set tab_label text. (gtk_notebook_query_menu_label): new function. get tab_label widget. (gtk_notebook_set_menu_label): new function. set tab_label widget. (gtk_notebook_set_menu_label_text): new function. set tab_label text. (gtk_notebook_set_tab_label_packing): new function. set tab_label fill, expand, fill_type (gtk_notebook_query_tab_label_packing): new function. get tab_label fill, expand, fill_type (gtk_notebook_real_page_position): return logic page number (gtk_notebook_search_page) search next/prev logic page (gtk_notebook_update_labels): set logic page number. (gtk_notebook_page_compare): renamed gtk_notebook_find_page (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK (gtk_notebook_button_press) (gtk_notebook_key_press) (gtk_notebook_focus) (gtk_notebook_pages_allocate) (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) use gtk_notebook_search_page (gtk_notebook_page_allocate): fixed allocation bug (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. (gtk_notebook_init): unset GTK_NO_WINDOW flag (gtk_notebook_size_request): check whether page->child is visible. changes due to tab h/vborder, homogeneous tabs (gtk_notebook_paint): don't draw invisible tabs (gtk_notebook_switch_page): calculate page_num if it's less than 0 (gtk_notebook_append_*) (gtk_notebook_prepend_*) (gtk_notebook_insert_page): removed sanity checks * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. --- ChangeLog | 45 + ChangeLog.pre-2-0 | 45 + ChangeLog.pre-2-10 | 45 + ChangeLog.pre-2-2 | 45 + ChangeLog.pre-2-4 | 45 + ChangeLog.pre-2-6 | 45 + ChangeLog.pre-2-8 | 45 + gtk/gtknotebook.c | 5702 +++++++++++++++++++++++++------------------- gtk/gtknotebook.h | 185 +- gtk/testgtk.c | 233 +- tests/testgtk.c | 233 +- 11 files changed, 3958 insertions(+), 2710 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index 536afd0797..f165b24b40 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -30,6 +30,7 @@ #define TAB_CURVATURE 1 #define ARROW_SIZE 12 #define ARROW_SPACING 0 +#define FOCUS_WIDTH 1 #define NOTEBOOK_INIT_SCROLL_DELAY (200) #define NOTEBOOK_SCROLL_DELAY (100) @@ -51,6 +52,8 @@ enum { ARG_SHOW_BORDER, ARG_SCROLLABLE, ARG_TAB_BORDER, + ARG_TAB_HBORDER, + ARG_TAB_VBORDER, ARG_PAGE, ARG_ENABLE_POPUP }; @@ -59,36 +62,33 @@ enum { CHILD_ARG_0, CHILD_ARG_TAB_LABEL, CHILD_ARG_MENU_LABEL, - CHILD_ARG_POSITION + CHILD_ARG_POSITION, + CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, + CHILD_ARG_TAB_PACK }; +/** GtkNotebook Methods **/ static void gtk_notebook_class_init (GtkNotebookClass *klass); static void gtk_notebook_init (GtkNotebook *notebook); -static void gtk_notebook_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); + +/** GtkObject Methods **/ +static void gtk_notebook_destroy (GtkObject *object); +static void gtk_notebook_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); static void gtk_notebook_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); -static void gtk_notebook_set_child_arg (GtkContainer *container, - GtkWidget *child, - GtkArg *arg, - guint arg_id); -static void gtk_notebook_get_child_arg (GtkContainer *container, - GtkWidget *child, - GtkArg *arg, - guint arg_id); -static void gtk_notebook_destroy (GtkObject *object); + +/** GtkWidget Methods **/ static void gtk_notebook_map (GtkWidget *widget); static void gtk_notebook_unmap (GtkWidget *widget); static void gtk_notebook_realize (GtkWidget *widget); -static void gtk_notebook_panel_realize (GtkNotebook *notebook); static void gtk_notebook_size_request (GtkWidget *widget, GtkRequisition *requisition); static void gtk_notebook_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static void gtk_notebook_paint (GtkWidget *widget, - GdkRectangle *area); static void gtk_notebook_draw (GtkWidget *widget, GdkRectangle *area); static gint gtk_notebook_expose (GtkWidget *widget, @@ -105,72 +105,100 @@ static gint gtk_notebook_motion_notify (GtkWidget *widget, GdkEventMotion *event); static gint gtk_notebook_key_press (GtkWidget *widget, GdkEventKey *event); +static gint gtk_notebook_focus_in (GtkWidget *widget, + GdkEventFocus *event); +static gint gtk_notebook_focus_out (GtkWidget *widget, + GdkEventFocus *event); +static void gtk_notebook_draw_focus (GtkWidget *widget); +static void gtk_notebook_style_set (GtkWidget *widget, + GtkStyle *previous_style); + +/** GtkContainer Methods **/ +static void gtk_notebook_set_child_arg (GtkContainer *container, + GtkWidget *child, + GtkArg *arg, + guint arg_id); +static void gtk_notebook_get_child_arg (GtkContainer *container, + GtkWidget *child, + GtkArg *arg, + guint arg_id); static void gtk_notebook_add (GtkContainer *container, GtkWidget *widget); static void gtk_notebook_remove (GtkContainer *container, GtkWidget *widget); -static void gtk_notebook_real_remove (GtkNotebook *notebook, - GList *list, - guint page_num); +static gint gtk_notebook_focus (GtkContainer *container, + GtkDirectionType direction); +static void gtk_notebook_set_focus_child (GtkContainer *container, + GtkWidget *child); +static GtkType gtk_notebook_child_type (GtkContainer *container); static void gtk_notebook_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); -static void gtk_notebook_switch_page (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num); + +/** GtkNotebook Private Functions **/ +static void gtk_notebook_panel_realize (GtkNotebook *notebook); +static void gtk_notebook_expose_tabs (GtkNotebook *notebook); +static void gtk_notebook_focus_changed (GtkNotebook *notebook, + GtkNotebookPage *old_page); +static void gtk_notebook_real_remove (GtkNotebook *notebook, + GList *list); +static void gtk_notebook_update_labels (GtkNotebook *notebook); +static gint gtk_notebook_timer (GtkNotebook *notebook); +static gint gtk_notebook_page_compare (gconstpointer a, + gconstpointer b); +static gint gtk_notebook_real_page_position (GtkNotebook *notebook, + GList *list); +static GList * gtk_notebook_search_page (GtkNotebook *notebook, + GList *list, + gint direction, + gboolean find_visible); + +/** GtkNotebook Drawing Functions **/ +static void gtk_notebook_paint (GtkWidget *widget, + GdkRectangle *area); static void gtk_notebook_draw_tab (GtkNotebook *notebook, GtkNotebookPage *page, GdkRectangle *area); -static void gtk_notebook_set_focus_child (GtkContainer *container, - GtkWidget *child); -static gint gtk_notebook_focus_in (GtkWidget *widget, - GdkEventFocus *event); -static gint gtk_notebook_focus_out (GtkWidget *widget, - GdkEventFocus *event); -static void gtk_notebook_draw_focus (GtkWidget *widget); -static void gtk_notebook_focus_changed (GtkNotebook *notebook, - GtkNotebookPage *old_page); +static void gtk_notebook_draw_arrow (GtkNotebook *notebook, + guint arrow); +static void gtk_notebook_set_shape (GtkNotebook *notebook); + +/** GtkNotebook Size Allocate Functions **/ static void gtk_notebook_pages_allocate (GtkNotebook *notebook, GtkAllocation *allocation); static void gtk_notebook_page_allocate (GtkNotebook *notebook, GtkNotebookPage *page, GtkAllocation *allocation); -static void gtk_notebook_draw_arrow (GtkNotebook *notebook, - guint arrow); -static gint gtk_notebook_timer (GtkNotebook *notebook); -static gint gtk_notebook_focus (GtkContainer *container, - GtkDirectionType direction); -static gint gtk_notebook_page_select (GtkNotebook *notebook); -static void gtk_notebook_calc_tabs (GtkNotebook *notebook, - GList *start, +static void gtk_notebook_calc_tabs (GtkNotebook *notebook, + GList *start, GList **end, gint *tab_space, guint direction); -static void gtk_notebook_expose_tabs (GtkNotebook *notebook); -static void gtk_notebook_switch_focus_tab (GtkNotebook *notebook, - GList *new_child); + +/** GtkNotebook Page Switch Methods **/ static void gtk_notebook_real_switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num); + +/** GtkNotebook Page Switch Functions **/ +static void gtk_notebook_switch_page (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num); +static gint gtk_notebook_page_select (GtkNotebook *notebook); +static void gtk_notebook_switch_focus_tab (GtkNotebook *notebook, + GList *new_child); static void gtk_notebook_menu_switch_page (GtkWidget *widget, GtkNotebookPage *page); -static void gtk_notebook_update_labels (GtkNotebook *notebook, - GList *list, - guint page_num); + +/** GtkNotebook Menu Functions **/ +static void gtk_notebook_menu_item_create (GtkNotebook *notebook, + GList *list); +static void gtk_notebook_menu_label_unparent (GtkWidget *widget, + gpointer data); static void gtk_notebook_menu_detacher (GtkWidget *widget, GtkMenu *menu); -static void gtk_notebook_menu_label_unparent (GtkWidget *widget, - gpointer data); -static void gtk_notebook_menu_item_create (GtkNotebook *notebook, - GtkNotebookPage *page, - gint position); -static GtkType gtk_notebook_child_type (GtkContainer *container); -static gint gtk_notebook_find_page (gconstpointer a, - gconstpointer b); -static void gtk_notebook_set_shape (GtkNotebook *notebook); -static void gtk_notebook_style_set (GtkWidget *widget, - GtkStyle *previous_style); + static GtkContainerClass *parent_class = NULL; static guint notebook_signals[LAST_SIGNAL] = { 0 }; @@ -215,6 +243,8 @@ gtk_notebook_class_init (GtkNotebookClass *class) gtk_object_add_arg_type ("GtkNotebook::page", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_PAGE); gtk_object_add_arg_type ("GtkNotebook::tab_pos", GTK_TYPE_POSITION_TYPE, GTK_ARG_READWRITE, ARG_TAB_POS); gtk_object_add_arg_type ("GtkNotebook::tab_border", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_TAB_BORDER); + gtk_object_add_arg_type ("GtkNotebook::tab_hborder", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_TAB_HBORDER); + gtk_object_add_arg_type ("GtkNotebook::tab_vborder", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_TAB_VBORDER); gtk_object_add_arg_type ("GtkNotebook::show_tabs", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SHOW_TABS); gtk_object_add_arg_type ("GtkNotebook::show_border", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SHOW_BORDER); gtk_object_add_arg_type ("GtkNotebook::scrollable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SCROLLABLE); @@ -223,14 +253,16 @@ gtk_notebook_class_init (GtkNotebookClass *class) gtk_container_add_child_arg_type ("GtkNotebook::tab_label", GTK_TYPE_STRING, GTK_ARG_READWRITE, CHILD_ARG_TAB_LABEL); gtk_container_add_child_arg_type ("GtkNotebook::menu_label", GTK_TYPE_STRING, GTK_ARG_READWRITE, CHILD_ARG_MENU_LABEL); gtk_container_add_child_arg_type ("GtkNotebook::position", GTK_TYPE_INT, GTK_ARG_READWRITE, CHILD_ARG_POSITION); + gtk_container_add_child_arg_type ("GtkNotebook::tab_fill", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_TAB_FILL); + gtk_container_add_child_arg_type ("GtkNotebook::tab_pack", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_TAB_PACK); notebook_signals[SWITCH_PAGE] = gtk_signal_new ("switch_page", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (GtkNotebookClass, switch_page), - gtk_marshal_NONE__POINTER_UINT, - GTK_TYPE_NONE, 2, + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (GtkNotebookClass, switch_page), + gtk_marshal_NONE__POINTER_UINT, + GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_UINT); @@ -271,9 +303,65 @@ gtk_notebook_class_init (GtkNotebookClass *class) } static void -gtk_notebook_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) +gtk_notebook_init (GtkNotebook *notebook) +{ + GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS); + GTK_WIDGET_UNSET_FLAGS (notebook, GTK_NO_WINDOW); + + notebook->cur_page = NULL; + notebook->children = NULL; + notebook->first_tab = NULL; + notebook->focus_tab = NULL; + notebook->panel = NULL; + notebook->menu = NULL; + + notebook->tab_border = 2; + notebook->tab_hborder = 2; + notebook->tab_vborder = 2; + + notebook->show_tabs = TRUE; + notebook->show_border = TRUE; + notebook->tab_pos = GTK_POS_TOP; + notebook->scrollable = FALSE; + notebook->in_child = 0; + notebook->click_child = 0; + notebook->button = 0; + notebook->need_timer = 0; + notebook->child_has_focus = FALSE; +} + +GtkWidget* +gtk_notebook_new (void) +{ + return GTK_WIDGET (gtk_type_new (gtk_notebook_get_type ())); +} + +/* Private GtkObject Methods : + * + * gtk_notebook_destroy + * gtk_notebook_set_arg + * gtk_notebook_get_arg + */ +static void +gtk_notebook_destroy (GtkObject *object) +{ + GtkNotebook *notebook; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (object)); + + notebook = GTK_NOTEBOOK (object); + + if (notebook->menu) + gtk_notebook_popup_disable (notebook); + + GTK_OBJECT_CLASS (parent_class)->destroy (object); +} + +static void +gtk_notebook_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id) { GtkNotebook *notebook; @@ -305,15 +393,21 @@ gtk_notebook_set_arg (GtkObject *object, case ARG_TAB_BORDER: gtk_notebook_set_tab_border (notebook, GTK_VALUE_UINT (*arg)); break; + case ARG_TAB_HBORDER: + gtk_notebook_set_tab_hborder (notebook, GTK_VALUE_UINT (*arg)); + break; + case ARG_TAB_VBORDER: + gtk_notebook_set_tab_vborder (notebook, GTK_VALUE_UINT (*arg)); + break; default: break; } } static void -gtk_notebook_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) +gtk_notebook_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id) { GtkNotebook *notebook; @@ -342,1822 +436,1834 @@ gtk_notebook_get_arg (GtkObject *object, case ARG_TAB_BORDER: GTK_VALUE_UINT (*arg) = notebook->tab_border; break; + case ARG_TAB_HBORDER: + GTK_VALUE_UINT (*arg) = notebook->tab_hborder; + break; + case ARG_TAB_VBORDER: + GTK_VALUE_UINT (*arg) = notebook->tab_vborder; + break; default: arg->type = GTK_TYPE_INVALID; break; } } +/* Private GtkWidget Methods : + * + * gtk_notebook_map + * gtk_notebook_unmap + * gtk_notebook_realize + * gtk_notebook_size_request + * gtk_notebook_size_allocate + * gtk_notebook_draw + * gtk_notebook_expose + * gtk_notebook_button_press + * gtk_notebook_button_release + * gtk_notebook_enter_notify + * gtk_notebook_leave_notify + * gtk_notebook_motion_notify + * gtk_notebook_key_press + * gtk_notebook_focus_in + * gtk_notebook_focus_out + * gtk_notebook_draw_focus + * gtk_notebook_style_set + */ static void -gtk_notebook_set_child_arg (GtkContainer *container, - GtkWidget *child, - GtkArg *arg, - guint arg_id) +gtk_notebook_map (GtkWidget *widget) { GtkNotebook *notebook; - GtkNotebookPage *page = NULL; - GList *list; - gint position; + GtkNotebookPage *page; + GList *children; - notebook = GTK_NOTEBOOK (container); + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - switch (arg_id) - { - case CHILD_ARG_TAB_LABEL: - /* a NULL pointer indicates a default_tab setting, otherwise - * we need to set the associated label - */ + GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); + gdk_window_show (widget->window); - if (!(list = g_list_find_custom (notebook->children, child, - gtk_notebook_find_page))) - return; + notebook = GTK_NOTEBOOK (widget); - page = list->data; + if (notebook->cur_page && + GTK_WIDGET_VISIBLE (notebook->cur_page->child) && + !GTK_WIDGET_MAPPED (notebook->cur_page->child)) + gtk_widget_map (notebook->cur_page->child); - if (GTK_VALUE_STRING (*arg)) - { - page->default_tab = FALSE; - if (page->tab_label) - gtk_widget_unparent (page->tab_label); - page->tab_label = gtk_label_new (GTK_VALUE_STRING (*arg)); - gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook)); - if (notebook->show_tabs) - { - gtk_widget_show (page->tab_label); - gtk_notebook_pages_allocate - (notebook, &(GTK_WIDGET (notebook)->allocation)); - gtk_notebook_expose_tabs (notebook); - } - } - else - { - page->default_tab = TRUE; - if (page->tab_label) - gtk_widget_unparent (page->tab_label); - if (!notebook->show_tabs) - page->tab_label = NULL; - else - { - gchar string[32]; - - sprintf (string, "Page %u", g_list_index (notebook->children, page) + 1); - page->tab_label = gtk_label_new (string); - gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook)); - gtk_widget_show (page->tab_label); - gtk_notebook_pages_allocate - (notebook, &(GTK_WIDGET (notebook)->allocation)); - gtk_notebook_expose_tabs (notebook); - } - } - break; - case CHILD_ARG_MENU_LABEL: + if (notebook->scrollable) + gtk_notebook_pages_allocate (notebook, &(widget->allocation)); + else + { + children = notebook->children; - for (position = 0, list = notebook->children; list; - list = list->next, position++) + while (children) { - page = list->data; - if (page->child == child) - break; - } + page = children->data; + children = children->next; - if (page->menu_label) - { - if (notebook->menu) - { - gtk_container_remove (GTK_CONTAINER (notebook->menu), - page->menu_label->parent); - gtk_widget_queue_resize (notebook->menu); - } - if (!page->default_menu) - gtk_widget_unref (page->menu_label); - } - if (GTK_VALUE_STRING (*arg)) - { - page->menu_label = gtk_label_new (GTK_VALUE_STRING (*arg)); - gtk_widget_ref (page->menu_label); - gtk_object_sink (GTK_OBJECT(page->menu_label)); - page->default_menu = FALSE; + if (page->tab_label && + GTK_WIDGET_VISIBLE (page->child) && + !GTK_WIDGET_MAPPED (page->tab_label)) + gtk_widget_map (page->tab_label); } - else - page->default_menu = TRUE; + } +} - if (notebook->menu) - gtk_notebook_menu_item_create (notebook, page, position); +static void +gtk_notebook_unmap (GtkWidget *widget) +{ + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - break; - case CHILD_ARG_POSITION: - gtk_notebook_reorder_child (notebook, child, GTK_VALUE_INT (*arg)); - break; - default: - break; - } + GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); + gdk_window_hide (widget->window); + if (GTK_NOTEBOOK (widget)->panel) + gdk_window_hide (GTK_NOTEBOOK (widget)->panel); } static void -gtk_notebook_get_child_arg (GtkContainer *container, - GtkWidget *child, - GtkArg *arg, - guint arg_id) +gtk_notebook_realize (GtkWidget *widget) { GtkNotebook *notebook; - GtkNotebookPage *page = NULL; - GList *list; + GdkWindowAttr attributes; + gint attributes_mask; - notebook = GTK_NOTEBOOK (container); + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - if (!(list = g_list_find_custom (notebook->children, child, - gtk_notebook_find_page))) - { - arg->type = GTK_TYPE_INVALID; - return; - } + notebook = GTK_NOTEBOOK (widget); + GTK_WIDGET_SET_FLAGS (notebook, GTK_REALIZED); - page = list->data; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.event_mask = gtk_widget_get_events (widget); + attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK); - switch (arg_id) - { - case CHILD_ARG_TAB_LABEL: - if (page->default_tab) - GTK_VALUE_STRING (*arg) = NULL; - else - { - if (page->tab_label && GTK_IS_LABEL (page->tab_label)) - GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (page->tab_label)->label); - else - GTK_VALUE_STRING (*arg) = NULL; - } - break; - case CHILD_ARG_MENU_LABEL: - if (page->default_menu) - GTK_VALUE_STRING (*arg) = NULL; - else - { - if (page->menu_label && GTK_IS_LABEL (page->menu_label)) - GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (page->menu_label)->label); - else - GTK_VALUE_STRING (*arg) = NULL; - } - break; - case CHILD_ARG_POSITION: - GTK_VALUE_INT (*arg) = g_list_position (notebook->children, list); - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -static GtkType -gtk_notebook_child_type (GtkContainer *container) -{ - return GTK_TYPE_WIDGET; -} - -static void -gtk_notebook_init (GtkNotebook *notebook) -{ - GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS); + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - notebook->cur_page = NULL; - notebook->children = NULL; - notebook->first_tab = NULL; - notebook->focus_tab = NULL; - notebook->panel = NULL; - notebook->menu = NULL; + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, notebook); - notebook->tab_border = 3; - notebook->show_tabs = TRUE; - notebook->show_border = TRUE; - notebook->tab_pos = GTK_POS_TOP; - notebook->scrollable = FALSE; - notebook->in_child = 0; - notebook->click_child = 0; - notebook->button = 0; - notebook->need_timer = 0; - notebook->child_has_focus = FALSE; -} + widget->style = gtk_style_attach (widget->style, widget->window); + gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); -GtkWidget* -gtk_notebook_new (void) -{ - return GTK_WIDGET (gtk_type_new (gtk_notebook_get_type ())); + gdk_window_set_back_pixmap (widget->window, NULL, TRUE); + if (notebook->scrollable) + gtk_notebook_panel_realize (notebook); } static void -gtk_notebook_destroy (GtkObject *object) +gtk_notebook_size_request (GtkWidget *widget, + GtkRequisition *requisition) { GtkNotebook *notebook; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (object)); + GtkNotebookPage *page; + GList *children; + gboolean switch_page = FALSE; + gint vis_pages; - notebook = GTK_NOTEBOOK (object); + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + g_return_if_fail (requisition != NULL); - if (notebook->menu) - gtk_notebook_popup_disable (notebook); + notebook = GTK_NOTEBOOK (widget); + widget->requisition.width = 0; + widget->requisition.height = 0; - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} + for (children = notebook->children, vis_pages = 0; children; + children = children->next) + { + page = children->data; -void -gtk_notebook_append_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); + if (GTK_WIDGET_VISIBLE (page->child)) + { + vis_pages++; + gtk_widget_size_request (page->child, &page->child->requisition); + + widget->requisition.width = MAX (widget->requisition.width, + page->child->requisition.width); + widget->requisition.height = MAX (widget->requisition.height, + page->child->requisition.height); - gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, -1); -} + if (GTK_WIDGET_MAPPED (page->child) && page != notebook->cur_page) + gtk_widget_unmap (page->child); + if (notebook->menu && page->menu_label->parent && + !GTK_WIDGET_VISIBLE (page->menu_label->parent)) + gtk_widget_show (page->menu_label->parent); + } + else + { + if (page == notebook->cur_page) + switch_page = TRUE; + if (notebook->menu && page->menu_label->parent && + GTK_WIDGET_VISIBLE (page->menu_label->parent)) + gtk_widget_hide (page->menu_label->parent); + } + } -void -gtk_notebook_append_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); + if (notebook->show_border || notebook->show_tabs) + { + widget->requisition.width += widget->style->klass->xthickness * 2; + widget->requisition.height += widget->style->klass->ythickness * 2; - gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, -1); -} + if (notebook->show_tabs) + { + gint tab_width = 0; + gint tab_height = 0; + gint tab_max = 0; + gint padding; + + for (children = notebook->children; children; + children = children->next) + { + page = children->data; + + if (GTK_WIDGET_VISIBLE (page->child)) + { + if (!GTK_WIDGET_VISIBLE (page->tab_label)) + gtk_widget_show (page->tab_label); -void -gtk_notebook_prepend_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); + gtk_widget_size_request (page->tab_label, + &page->tab_label->requisition); - gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, 0); -} + page->requisition.width = + page->tab_label->requisition.width + + 2 * widget->style->klass->xthickness; + page->requisition.height = + page->tab_label->requisition.height + + 2 * widget->style->klass->ythickness; + + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + page->requisition.height += 2 * (notebook->tab_vborder + + FOCUS_WIDTH); + tab_height = MAX (tab_height, page->requisition.height); + tab_max = MAX (tab_max, page->requisition.width); + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + page->requisition.width += 2 * (notebook->tab_hborder + + FOCUS_WIDTH); + tab_width = MAX (tab_width, page->requisition.width); + tab_max = MAX (tab_max, page->requisition.height); + break; + } + } + else if (GTK_WIDGET_VISIBLE (page->tab_label)) + gtk_widget_hide (page->tab_label); + } -void -gtk_notebook_prepend_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); + children = notebook->children; - gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, 0); -} + if (vis_pages) + { + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + if (tab_height == 0) + break; -void -gtk_notebook_insert_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - gint position) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); + if (notebook->scrollable && vis_pages > 1 && + widget->requisition.width < tab_width) + tab_height = MAX (tab_height, ARROW_SIZE); - gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position); -} + padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH + + notebook->tab_hborder) - TAB_OVERLAP; + tab_max += padding; + while (children) + { + page = children->data; + children = children->next; + + if (!GTK_WIDGET_VISIBLE (page->child)) + continue; -void -gtk_notebook_insert_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label, - gint position) -{ - GtkNotebookPage *page; - gint nchildren; + if (notebook->homogeneous) + page->requisition.width = tab_max; + else + page->requisition.width += padding; - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); + tab_width += page->requisition.width; + page->requisition.height = tab_height; + } - page = g_new (GtkNotebookPage, 1); - page->child = child; - page->requisition.width = 0; - page->requisition.height = 0; - page->allocation.x = 0; - page->allocation.y = 0; - page->allocation.width = 0; - page->allocation.height = 0; - page->default_menu = FALSE; - page->default_tab = FALSE; - - nchildren = g_list_length (notebook->children); - if ((position < 0) || (position > nchildren)) - position = nchildren; + if (notebook->scrollable && vis_pages > 1 && + widget->requisition.width < tab_width) + tab_width = tab_max + 2 * (ARROW_SIZE + ARROW_SPACING); - notebook->children = g_list_insert (notebook->children, page, position); + if (notebook->homogeneous && !notebook->scrollable) + widget->requisition.width = MAX (widget->requisition.width, + vis_pages * tab_max + + TAB_OVERLAP); + else + widget->requisition.width = MAX (widget->requisition.width, + tab_width + TAB_OVERLAP); - if (!tab_label) - { - page->default_tab = TRUE; - if (notebook->show_tabs) - tab_label = gtk_label_new (""); - } - page->tab_label = tab_label; - page->menu_label = menu_label; + widget->requisition.height += tab_height; + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + if (tab_width == 0) + break; - if (!menu_label) - page->default_menu = TRUE; - else - { - gtk_widget_ref (page->menu_label); - gtk_object_sink (GTK_OBJECT(page->menu_label)); - } + if (notebook->scrollable && vis_pages > 1 && + widget->requisition.height < tab_height) + tab_width = MAX (tab_width, ARROW_SPACING +2 * ARROW_SIZE); - if (notebook->menu) - gtk_notebook_menu_item_create (notebook, page, position); + padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH + + notebook->tab_vborder) - TAB_OVERLAP; + tab_max += padding; - gtk_notebook_update_labels - (notebook, g_list_nth (notebook->children, position), position + 1); + while (children) + { + page = children->data; + children = children->next; - if (!notebook->first_tab) - notebook->first_tab = notebook->children; + if (!GTK_WIDGET_VISIBLE (page->child)) + continue; - gtk_widget_set_parent (child, GTK_WIDGET (notebook)); - if (tab_label) - { - gtk_widget_set_parent (tab_label, GTK_WIDGET (notebook)); - gtk_widget_show (tab_label); - } + page->requisition.width = tab_width; - if (!notebook->cur_page) - { - gtk_notebook_switch_page (notebook, page, 0); - gtk_notebook_switch_focus_tab (notebook, NULL); - } + if (notebook->homogeneous) + page->requisition.height = tab_max; + else + page->requisition.height += padding; - if (GTK_WIDGET_VISIBLE (notebook)) - { - if (GTK_WIDGET_REALIZED (notebook) && - !GTK_WIDGET_REALIZED (child)) - gtk_widget_realize (child); - - if (GTK_WIDGET_MAPPED (notebook) && - !GTK_WIDGET_MAPPED (child) && notebook->cur_page == page) - gtk_widget_map (child); + tab_height += page->requisition.height; + } - if (tab_label) - { - if (GTK_WIDGET_REALIZED (notebook) && - !GTK_WIDGET_REALIZED (tab_label)) - gtk_widget_realize (tab_label); - - if (GTK_WIDGET_MAPPED (notebook) && - !GTK_WIDGET_MAPPED (tab_label)) - gtk_widget_map (tab_label); + if (notebook->scrollable && vis_pages > 1 && + widget->requisition.height < tab_height) + tab_height = tab_max + ARROW_SIZE + ARROW_SPACING; + + widget->requisition.width += tab_width; + + if (notebook->homogeneous && !notebook->scrollable) + widget->requisition.height = + MAX (widget->requisition.height, + vis_pages * tab_max + TAB_OVERLAP); + else + widget->requisition.height = + MAX (widget->requisition.height, + tab_height + TAB_OVERLAP); + + if (!notebook->homogeneous || notebook->scrollable) + vis_pages = 1; + widget->requisition.height = MAX (widget->requisition.height, + vis_pages * tab_max + + TAB_OVERLAP); + break; + } + } } } - if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (notebook)) - gtk_widget_queue_resize (child); -} - -void -gtk_notebook_remove_page (GtkNotebook *notebook, - gint page_num) -{ - GList *list; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + widget->requisition.width += GTK_CONTAINER (widget)->border_width * 2; + widget->requisition.height += GTK_CONTAINER (widget)->border_width * 2; - if (page_num >= 0) + if (switch_page) { - list = g_list_nth (notebook->children, page_num); - if (list) - gtk_notebook_real_remove (notebook, list, page_num); + if (vis_pages) + { + for (children = notebook->children; children; + children = children->next) + { + page = children->data; + if (GTK_WIDGET_VISIBLE (page->child)) + { + gtk_notebook_switch_page (notebook, page, -1); + break; + } + } + } + else if (GTK_WIDGET_VISIBLE (widget)) + { + widget->requisition.width = GTK_CONTAINER (widget)->border_width * 2; + widget->requisition.height= GTK_CONTAINER (widget)->border_width * 2; + } } - else + if (vis_pages && !notebook->cur_page) { - list = g_list_last (notebook->children); - if (list) - gtk_notebook_real_remove - (notebook, list, g_list_index (notebook->children, list->data)); + children = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE); + if (children) + { + notebook->first_tab = children; + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (children),-1); + } } } static void -gtk_notebook_add (GtkContainer *container, - GtkWidget *widget) -{ - g_return_if_fail (container != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (container)); - g_return_if_fail (widget != NULL); - - gtk_notebook_insert_page_menu (GTK_NOTEBOOK (container), widget, - NULL, NULL, -1); -} - -static void -gtk_notebook_remove (GtkContainer *container, - GtkWidget *widget) +gtk_notebook_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) { GtkNotebook *notebook; GtkNotebookPage *page; + GtkAllocation child_allocation; GList *children; - guint page_num; - g_return_if_fail (container != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (container)); g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + g_return_if_fail (allocation != NULL); - notebook = GTK_NOTEBOOK (container); + widget->allocation = *allocation; + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); - children = notebook->children; - page_num = 0; - while (children) + notebook = GTK_NOTEBOOK (widget); + if (notebook->children) { - page = children->data; - if (page->child == widget) + child_allocation.x = GTK_CONTAINER (widget)->border_width; + child_allocation.y = GTK_CONTAINER (widget)->border_width; + child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2); + child_allocation.height = MAX (1, allocation->height - child_allocation.y * 2); + + if (notebook->show_tabs || notebook->show_border) { - gtk_notebook_real_remove (notebook, children, page_num); - break; + child_allocation.x += widget->style->klass->xthickness; + child_allocation.y += widget->style->klass->ythickness; + child_allocation.width = MAX (1, child_allocation.width - + widget->style->klass->xthickness * 2); + child_allocation.height = MAX (1, child_allocation.height - + widget->style->klass->ythickness * 2); + + if (notebook->show_tabs && notebook->children && notebook->cur_page) + { + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + child_allocation.y += notebook->cur_page->requisition.height; + case GTK_POS_BOTTOM: + child_allocation.height = + MAX (1, child_allocation.height - + notebook->cur_page->requisition.height); + break; + case GTK_POS_LEFT: + child_allocation.x += notebook->cur_page->requisition.width; + case GTK_POS_RIGHT: + child_allocation.width = + MAX (1, child_allocation.width - + notebook->cur_page->requisition.width); + break; + } + } } - page_num++; - children = children->next; + + children = notebook->children; + while (children) + { + page = children->data; + children = children->next; + + if (GTK_WIDGET_VISIBLE (page->child)) + gtk_widget_size_allocate (page->child, &child_allocation); + } + + gtk_notebook_pages_allocate (notebook, allocation); } + gtk_notebook_set_shape (notebook); } -gint -gtk_notebook_page_num (GtkNotebook *notebook, - GtkWidget *child) +static void +gtk_notebook_draw (GtkWidget *widget, + GdkRectangle *area) { - GList *children; - gint num; + GtkNotebook *notebook; + GdkRectangle child_area; - g_return_val_if_fail (notebook != NULL, -1); - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + g_return_if_fail (area != NULL); - num = 0; - children = notebook->children; - while (children) + if (GTK_WIDGET_DRAWABLE (widget)) { - GtkNotebookPage *page; + notebook = GTK_NOTEBOOK (widget); - page = children->data; - if (page->child == child) - return num; + gtk_notebook_paint (widget, area); + gtk_widget_draw_focus (widget); - children = children->next; - num++; + if (notebook->cur_page && + gtk_widget_intersect (notebook->cur_page->child, area, &child_area)) + gtk_widget_draw (notebook->cur_page->child, &child_area); } - - return -1; } -static void -gtk_notebook_real_remove (GtkNotebook *notebook, - GList *list, - guint page_num) +static gint +gtk_notebook_expose (GtkWidget *widget, + GdkEventExpose *event) { - GtkNotebookPage *page; - GList * next_list; - gint need_resize = FALSE; - - if (list->prev) - { - next_list = list->prev; - page_num--; - } - else if (list->next) - { - next_list = list->next; - page_num++; - } - else - next_list = NULL; - - if (notebook->cur_page == list->data) - { - notebook->cur_page = NULL; - if (next_list) - { - page = next_list->data; - gtk_notebook_switch_page (notebook, page, page_num); - } - } - - if (list == notebook->first_tab) - notebook->first_tab = next_list; - if (list == notebook->focus_tab) - gtk_notebook_switch_focus_tab (notebook, next_list); - - page = list->data; - - if ((GTK_WIDGET_VISIBLE (page->child) || - (page->tab_label && GTK_WIDGET_VISIBLE (page->tab_label))) - && GTK_WIDGET_VISIBLE (notebook)) - need_resize = TRUE; + GtkNotebook *notebook; + GdkEventExpose child_event; + GdkRectangle child_area; + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - gtk_widget_unparent (page->child); + if (GTK_WIDGET_DRAWABLE (widget)) + { + notebook = GTK_NOTEBOOK (widget); - if (page->tab_label) - gtk_widget_unparent (page->tab_label); + gtk_notebook_paint (widget, &event->area); + if (notebook->cur_page && + gtk_widget_intersect (notebook->cur_page->tab_label, + &event->area, &child_area)) + gtk_widget_draw_focus (widget); - if (notebook->menu) - { - gtk_container_remove (GTK_CONTAINER (notebook->menu), - page->menu_label->parent); - gtk_widget_queue_resize (notebook->menu); + child_event = *event; + if (notebook->cur_page && + GTK_WIDGET_NO_WINDOW (notebook->cur_page->child) && + gtk_widget_intersect (notebook->cur_page->child, &event->area, + &child_event.area)) + gtk_widget_event (notebook->cur_page->child, (GdkEvent*) &child_event); } - if (!page->default_menu) - gtk_widget_unref (page->menu_label); - - gtk_notebook_update_labels (notebook, list->next, page_num + 1); - - notebook->children = g_list_remove_link (notebook->children, list); - g_list_free (list); - g_free (page); - - if (need_resize) - gtk_widget_queue_resize (GTK_WIDGET (notebook)); + return FALSE; } -gint -gtk_notebook_current_page (GtkNotebook *notebook) +static gint +gtk_notebook_button_press (GtkWidget *widget, + GdkEventButton *event) { + GtkNotebook *notebook; + GtkNotebookPage *page; GList *children; - gint cur_page; + gint num; - g_return_val_if_fail (notebook != NULL, -1); - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - if (notebook->cur_page) - { - cur_page = 0; - children = notebook->children; + notebook = GTK_NOTEBOOK (widget); - while (children) - { - if (children->data == notebook->cur_page) - break; - children = children->next; - cur_page += 1; - } + if (event->type != GDK_BUTTON_PRESS || !notebook->children || + notebook->button) + return FALSE; - if (!children) - cur_page = -1; - } - else + if (event->window == notebook->panel) { - cur_page = -1; - } + if (!GTK_WIDGET_HAS_FOCUS (widget)) + gtk_widget_grab_focus (widget); - return cur_page; -} + gtk_grab_add (widget); + notebook->button = event->button; -void -gtk_notebook_set_page (GtkNotebook *notebook, - gint page_num) -{ - GList *list; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + if (event->x <= ARROW_SIZE + ARROW_SPACING / 2) + { + notebook->click_child = GTK_ARROW_LEFT; + if (event->button == 1) + { + if (!notebook->focus_tab || + gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_PREV, TRUE)) + gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT); - if (page_num >= 0) - { - list = g_list_nth (notebook->children, page_num); - if (list) - gtk_notebook_switch_page (notebook, list->data, page_num); + if (!notebook->timer) + { + notebook->timer = gtk_timeout_add + (NOTEBOOK_INIT_SCROLL_DELAY, + (GtkFunction) gtk_notebook_timer, (gpointer) notebook); + notebook->need_timer = TRUE; + } + } + else if (event->button == 2) + gtk_notebook_page_select (GTK_NOTEBOOK (widget)); + else if (event->button == 3) + gtk_notebook_switch_focus_tab (notebook, + gtk_notebook_search_page (notebook, + NULL, + STEP_NEXT, + TRUE)); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + } + else + { + notebook->click_child = GTK_ARROW_RIGHT; + if (event->button == 1) + { + if (!notebook->focus_tab || + gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_NEXT, TRUE)) + gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_RIGHT); + + if (!notebook->timer) + { + notebook->timer = gtk_timeout_add + (NOTEBOOK_INIT_SCROLL_DELAY, + (GtkFunction) gtk_notebook_timer, (gpointer) notebook); + notebook->need_timer = TRUE; + } + } + else if (event->button == 2) + gtk_notebook_page_select (GTK_NOTEBOOK (widget)); + else if (event->button == 3) + gtk_notebook_switch_focus_tab + (notebook, gtk_notebook_search_page (notebook, NULL, + STEP_PREV, TRUE)); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + } } - else + else if (event->window == widget->window) { - list = g_list_last (notebook->children); - if (list) - gtk_notebook_switch_page (notebook, list->data, - g_list_index (notebook->children, list->data)); + if (event->button == 3 && notebook->menu) + { + gtk_menu_popup (GTK_MENU (notebook->menu), NULL, NULL, + NULL, NULL, 3, event->time); + return FALSE; + } + + num = 0; + children = notebook->children; + while (children) + { + page = children->data; + + if (GTK_WIDGET_VISIBLE (page->child) && + page->tab_label && GTK_WIDGET_MAPPED (page->tab_label) && + (event->x >= page->allocation.x) && + (event->y >= page->allocation.y) && + (event->x <= (page->allocation.x + page->allocation.width)) && + (event->y <= (page->allocation.y + page->allocation.height))) + { + if (page == notebook->cur_page && notebook->focus_tab && + notebook->focus_tab != children && + GTK_WIDGET_HAS_FOCUS (notebook)) + { + GtkNotebookPage *old_page; + + notebook->child_has_focus = FALSE; + old_page = (GtkNotebookPage *) + (notebook->focus_tab->data); + gtk_notebook_switch_focus_tab (notebook, children); + gtk_notebook_focus_changed (notebook, old_page); + } + else + { + gtk_notebook_switch_focus_tab (notebook, children); + gtk_notebook_switch_page (notebook, page, num); + gtk_widget_grab_focus (widget); + } + break; + } + children = children->next; + num++; + } + if (!children && !GTK_WIDGET_HAS_FOCUS (widget)) + gtk_widget_grab_focus (widget); } + gtk_notebook_set_shape (notebook); + return FALSE; } -void -gtk_notebook_next_page (GtkNotebook *notebook) +static gint +gtk_notebook_button_release (GtkWidget *widget, + GdkEventButton *event) { - GtkNotebookPage *page; - GList *children; - gint num; + GtkNotebook *notebook; - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - children = notebook->children; - num = 0; - while (children) - { - if (notebook->cur_page == children->data) - break; - children = children->next; - num++; - } + if (event->type != GDK_BUTTON_RELEASE) + return FALSE; - if (!children) - return; + notebook = GTK_NOTEBOOK (widget); - if (children->next) - { - children = children->next; - num++; - } - else + if (event->button == notebook->button) { - children = notebook->children; - num = 0; - } + guint click_child; - page = children->data; - gtk_notebook_switch_page (notebook, page, num); + if (notebook->timer) + { + gtk_timeout_remove (notebook->timer); + notebook->timer = 0; + notebook->need_timer = FALSE; + } + gtk_grab_remove (widget); + click_child = notebook->click_child; + notebook->click_child = 0; + notebook->button = 0; + gtk_notebook_draw_arrow (notebook, click_child); + + } + return FALSE; } -void -gtk_notebook_prev_page (GtkNotebook *notebook) +static gint +gtk_notebook_enter_notify (GtkWidget *widget, + GdkEventCrossing *event) { - GtkNotebookPage *page; - GList *children; - gint num; + GtkNotebook *notebook; - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - children = notebook->children; - num = 0; - while (children) + notebook = GTK_NOTEBOOK (widget); + + if (event->window == notebook->panel) { - if (notebook->cur_page == children->data) - break; - children = children->next; - num++; - } + gint x; + gint y; - if (!children) - return; + gdk_window_get_pointer (notebook->panel, &x, &y, NULL); - if (children->prev) - { - children = children->prev; - num--; - } - else - { - while (children->next) + if (x <= ARROW_SIZE + ARROW_SPACING / 2) { - children = children->next; - num++; + notebook->in_child = GTK_ARROW_LEFT; + + if (notebook->click_child == 0) + gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + } + else + { + notebook->in_child = GTK_ARROW_RIGHT; + + if (notebook->click_child == 0) + gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); } } - page = children->data; - gtk_notebook_switch_page (notebook, page, num); + return FALSE; } -void -gtk_notebook_reorder_child (GtkNotebook *notebook, - GtkWidget *child, - gint position) +static gint +gtk_notebook_leave_notify (GtkWidget *widget, + GdkEventCrossing *event) { - GList *list; - GtkNotebookPage *page; - gint old_pos; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); - g_return_if_fail (GTK_IS_WIDGET (child)); + GtkNotebook *notebook; - for (old_pos = 0, list = notebook->children; list; - list = list->next, old_pos++) - { - page = list->data; - if (page->child == child) - break; - } + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - if (!list || old_pos == position) - return; + notebook = GTK_NOTEBOOK (widget); - notebook->children = g_list_remove_link (notebook->children, list); - - if (position <= 0 || !notebook->children) - { - list->next = notebook->children; - if (list->next) - list->next->prev = list; - notebook->children = list; - } - else + if (event->window == notebook->panel && !notebook->click_child) { - GList *work; - - if ((work = g_list_nth (notebook->children, position))) + if (notebook->in_child == GTK_ARROW_LEFT) { - list->prev = work->prev; - if (list->prev) - list->prev->next = list; - list->next = work; - work->prev = list; + notebook->in_child = 0; + gtk_notebook_draw_arrow (notebook,GTK_ARROW_LEFT); } else { - work = g_list_last (notebook->children); - work->next = list; - list->prev = work; + notebook->in_child = 0; + gtk_notebook_draw_arrow (notebook,GTK_ARROW_RIGHT); } } + return FALSE; +} - if (notebook->menu) - { - GtkWidget *menu_item; - - menu_item = page->menu_label->parent; - gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label); - gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item); - gtk_notebook_menu_item_create (notebook, page, position); - gtk_widget_queue_resize (notebook->menu); - } +static gint +gtk_notebook_motion_notify (GtkWidget *widget, + GdkEventMotion *event) +{ + GtkNotebook *notebook; - gtk_notebook_update_labels (notebook, notebook->children, 1); + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - if (notebook->show_tabs) - { - gtk_notebook_pages_allocate (notebook, - &(GTK_WIDGET (notebook)->allocation)); - gtk_notebook_expose_tabs (notebook); - } -} - -static void -gtk_notebook_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - GtkNotebook *notebook; - GList *children; - - g_return_if_fail (container != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (container)); - g_return_if_fail (callback != NULL); - - notebook = GTK_NOTEBOOK (container); + notebook = GTK_NOTEBOOK (widget); - children = notebook->children; - while (children) + if (notebook->button) + return FALSE; + + if (event->window == notebook->panel) { - GtkNotebookPage *page; + gint x; - page = children->data; - children = children->next; - (* callback) (page->child, callback_data); - if (include_internals) - { - if (page->tab_label) - (* callback) (page->tab_label, callback_data); - if (page->menu_label) - (* callback) (page->menu_label, callback_data); - } + x = event->x; + if (event->is_hint) + gdk_window_get_pointer (notebook->panel, &x, NULL, NULL); + + if (x <= ARROW_SIZE + ARROW_SPACING / 2 && + notebook->in_child == GTK_ARROW_RIGHT) + { + notebook->in_child = GTK_ARROW_LEFT; + gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + } + else if (x > ARROW_SIZE + ARROW_SPACING / 2 && + notebook->in_child == GTK_ARROW_LEFT) + { + notebook->in_child = GTK_ARROW_RIGHT; + gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + } + return FALSE; } + return FALSE; } -static void -gtk_notebook_expose_tabs (GtkNotebook *notebook) +static gint +gtk_notebook_key_press (GtkWidget *widget, + GdkEventKey *event) { - GtkWidget *widget; - GtkNotebookPage *page; - GdkEventExpose event; - gint border; + GtkNotebook *notebook; + GtkDirectionType direction = 0; + GList *list; - widget = GTK_WIDGET (notebook); - border = GTK_CONTAINER (notebook)->border_width; + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - page = notebook->first_tab->data; + notebook = GTK_NOTEBOOK (widget); - event.type = GDK_EXPOSE; - event.window = widget->window; - event.count = 0; - event.area.x = border; - event.area.y = border; + if (!notebook->children || !notebook->show_tabs) + return FALSE; - switch (notebook->tab_pos) + switch (event->keyval) { - case GTK_POS_BOTTOM: - event.area.y = widget->allocation.height - border - - page->allocation.height - widget->style->klass->ythickness; - if (notebook->first_tab->data != notebook->cur_page) - event.area.y -= widget->style->klass->ythickness; - case GTK_POS_TOP: - event.area.width = widget->allocation.width - 2 * border; - event.area.height = page->allocation.height - + widget->style->klass->ythickness; - if (notebook->first_tab->data != notebook->cur_page) - event.area.height += widget->style->klass->ythickness; + case GDK_Up: + direction = GTK_DIR_UP; break; - case GTK_POS_RIGHT: - event.area.x = widget->allocation.width - border - - page->allocation.width - widget->style->klass->xthickness; - if (notebook->first_tab->data != notebook->cur_page) - event.area.x -= widget->style->klass->xthickness; - case GTK_POS_LEFT: - event.area.width = page->allocation.width - + widget->style->klass->xthickness; - event.area.height = widget->allocation.height - 2 * border; - if (notebook->first_tab->data != notebook->cur_page) - event.area.width += widget->style->klass->xthickness; + case GDK_Left: + direction = GTK_DIR_LEFT; break; - } - gtk_widget_event (widget, (GdkEvent *) &event); + case GDK_Down: + direction = GTK_DIR_DOWN; + break; + case GDK_Right: + direction = GTK_DIR_RIGHT; + break; + case GDK_Tab: + case GDK_ISO_Left_Tab: + if (event->state & GDK_SHIFT_MASK) + direction = GTK_DIR_TAB_BACKWARD; + else + direction = GTK_DIR_TAB_FORWARD; + break; + case GDK_Home: + list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE); + if (list) + gtk_notebook_switch_focus_tab (notebook, list); + return TRUE; + case GDK_End: + list = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE); + if (list) + gtk_notebook_switch_focus_tab (notebook, list); + return TRUE; + case GDK_Return: + case GDK_space: + gtk_notebook_page_select (GTK_NOTEBOOK (widget)); + return TRUE; + default: + return FALSE; + } + return gtk_container_focus (GTK_CONTAINER (widget), direction); } -void -gtk_notebook_set_tab_pos (GtkNotebook *notebook, - GtkPositionType pos) +static gint +gtk_notebook_focus_in (GtkWidget *widget, + GdkEventFocus *event) { - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - if (notebook->tab_pos != pos) - { - notebook->tab_pos = pos; + GTK_NOTEBOOK (widget)->child_has_focus = FALSE; + GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); + gtk_widget_draw_focus (widget); - if (GTK_WIDGET_VISIBLE (notebook)) - gtk_widget_queue_resize (GTK_WIDGET (notebook)); - } + return FALSE; } -void -gtk_notebook_set_show_tabs (GtkNotebook *notebook, - gboolean show_tabs) +static gint +gtk_notebook_focus_out (GtkWidget *widget, + GdkEventFocus *event) { - GtkNotebookPage *page; - GList *children; + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); + gtk_widget_draw_focus (widget); - show_tabs = show_tabs != FALSE; + return FALSE; +} - if (notebook->show_tabs == show_tabs) - return; +static void +gtk_notebook_draw_focus (GtkWidget *widget) +{ + GtkNotebook *notebook; - notebook->show_tabs = show_tabs; - children = notebook->children; + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - if (!show_tabs) - { - GTK_WIDGET_UNSET_FLAGS (notebook, GTK_CAN_FOCUS); - - while (children) - { - page = children->data; - children = children->next; - if (page->default_tab) - { - gtk_widget_destroy (page->tab_label); - page->tab_label = NULL; - } - else - gtk_widget_hide (page->tab_label); - } - - if (notebook->panel) - gdk_window_hide (notebook->panel); - } - else + notebook = GTK_NOTEBOOK (widget); + + if (GTK_WIDGET_DRAWABLE (widget) && notebook->show_tabs && + notebook->focus_tab) { - gchar string[32]; - gint i = 1; - - GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS); - - while (children) - { - page = children->data; - children = children->next; - if (page->default_tab) - { - sprintf (string, "Page %d", i); - page->tab_label = gtk_label_new (string); - gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook)); - } - gtk_widget_show (page->tab_label); - i++; - } + GtkNotebookPage *page; + GdkRectangle area; + + page = notebook->focus_tab->data; + + area.x = widget->allocation.x; + area.y = widget->allocation.y; + area.width = widget->allocation.width; + area.height = widget->allocation.height; + + gtk_notebook_draw_tab(GTK_NOTEBOOK(widget), page, &area); } - gtk_widget_queue_resize (GTK_WIDGET (notebook)); } -void -gtk_notebook_set_show_border (GtkNotebook *notebook, - gint show_border) +static void +gtk_notebook_style_set (GtkWidget *widget, + GtkStyle *previous_style) { - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - if (notebook->show_border != show_border) + if (GTK_WIDGET_REALIZED (widget) && + !GTK_WIDGET_NO_WINDOW (widget)) { - notebook->show_border = show_border; - - if (GTK_WIDGET_VISIBLE (notebook)) - gtk_widget_queue_resize (GTK_WIDGET (notebook)); + gtk_style_set_background (widget->style, widget->window, widget->state); + if (GTK_WIDGET_DRAWABLE (widget)) + gdk_window_clear (widget->window); } + + gtk_widget_queue_draw (widget); + gtk_notebook_set_shape (GTK_NOTEBOOK(widget)); } -void -gtk_notebook_set_scrollable (GtkNotebook *notebook, - gint scrollable) +/* Private GtkContainer Methods : + * + * gtk_notebook_set_child_arg + * gtk_notebook_get_child_arg + * gtk_notebook_add + * gtk_notebook_remove + * gtk_notebook_focus + * gtk_notebook_set_focus_child + * gtk_notebook_child_type + * gtk_notebook_forall + */ +static void +gtk_notebook_set_child_arg (GtkContainer *container, + GtkWidget *child, + GtkArg *arg, + guint arg_id) { - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - scrollable = (scrollable != FALSE); + gboolean expand; + gboolean fill; + GtkPackType pack_type; - if (scrollable != notebook->scrollable) + switch (arg_id) { - notebook->scrollable = scrollable; - - if (GTK_WIDGET_REALIZED (notebook)) - { - if (scrollable) - { - gtk_notebook_panel_realize (notebook); - } - else if (notebook->panel) - { - gdk_window_destroy (notebook->panel); - notebook->panel = NULL; - } - } - - if (GTK_WIDGET_VISIBLE (notebook)) - gtk_widget_queue_resize (GTK_WIDGET(notebook)); + case CHILD_ARG_TAB_LABEL: + /* a NULL pointer indicates a default_tab setting, otherwise + * we need to set the associated label + */ + gtk_notebook_set_tab_label_text (GTK_NOTEBOOK (container), child, + GTK_VALUE_STRING(*arg)); + break; + case CHILD_ARG_MENU_LABEL: + gtk_notebook_set_menu_label_text (GTK_NOTEBOOK (container), child, + GTK_VALUE_STRING (*arg)); + break; + case CHILD_ARG_POSITION: + gtk_notebook_reorder_child (GTK_NOTEBOOK (container), child, + GTK_VALUE_INT (*arg)); + break; + case CHILD_ARG_TAB_EXPAND: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + &expand, &fill, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child, + GTK_VALUE_BOOL (*arg), + fill, pack_type); + break; + case CHILD_ARG_TAB_FILL: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + &expand, &fill, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child, + expand, + GTK_VALUE_BOOL (*arg), + pack_type); + break; + case CHILD_ARG_TAB_PACK: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + &expand, &fill, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child, + expand, fill, + GTK_VALUE_BOOL (*arg)); + break; + default: + break; } } static void -gtk_notebook_map (GtkWidget *widget) +gtk_notebook_get_child_arg (GtkContainer *container, + GtkWidget *child, + GtkArg *arg, + guint arg_id) { + GList *list; GtkNotebook *notebook; - GtkNotebookPage *page; - GList *children; + GtkWidget *label; + gboolean expand; + gboolean fill; + GtkPackType pack_type; - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - - GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); - gdk_window_show (widget->window); - - notebook = GTK_NOTEBOOK (widget); + notebook = GTK_NOTEBOOK (container); - if (notebook->cur_page && - GTK_WIDGET_VISIBLE (notebook->cur_page->child) && - !GTK_WIDGET_MAPPED (notebook->cur_page->child)) - gtk_widget_map (notebook->cur_page->child); + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + { + arg->type = GTK_TYPE_INVALID; + return; + } - if (notebook->scrollable) - gtk_notebook_pages_allocate (notebook, &(widget->allocation)); - else + switch (arg_id) { - children = notebook->children; + case CHILD_ARG_TAB_LABEL: + label = gtk_notebook_query_tab_label (notebook, child); - while (children) - { - page = children->data; - children = children->next; + if (label && GTK_IS_LABEL (label)) + GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (label)->label); + else + GTK_VALUE_STRING (*arg) = NULL; + break; + case CHILD_ARG_MENU_LABEL: + label = gtk_notebook_query_menu_label (notebook, child); - if (page->tab_label && - GTK_WIDGET_VISIBLE (page->child) && - !GTK_WIDGET_MAPPED (page->tab_label)) - gtk_widget_map (page->tab_label); - } + if (label && GTK_IS_LABEL (label)) + GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (label)->label); + else + GTK_VALUE_STRING (*arg) = NULL; + break; + case CHILD_ARG_POSITION: + GTK_VALUE_INT (*arg) = g_list_position (notebook->children, list); + break; + case CHILD_ARG_TAB_EXPAND: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + &expand, NULL, NULL); + GTK_VALUE_BOOL (*arg) = expand; + break; + case CHILD_ARG_TAB_FILL: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + NULL, &fill, NULL); + GTK_VALUE_BOOL (*arg) = fill; + break; + case CHILD_ARG_TAB_PACK: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + NULL, NULL, &pack_type); + GTK_VALUE_BOOL (*arg) = pack_type; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; } } static void -gtk_notebook_unmap (GtkWidget *widget) +gtk_notebook_add (GtkContainer *container, + GtkWidget *widget) { - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (container)); - GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); - gdk_window_hide (widget->window); - if (GTK_NOTEBOOK (widget)->panel) - gdk_window_hide (GTK_NOTEBOOK (widget)->panel); + gtk_notebook_insert_page_menu (GTK_NOTEBOOK (container), widget, + NULL, NULL, -1); } static void -gtk_notebook_realize (GtkWidget *widget) +gtk_notebook_remove (GtkContainer *container, + GtkWidget *widget) { GtkNotebook *notebook; - GdkWindowAttr attributes; - gint attributes_mask; + GtkNotebookPage *page; + GList *children; + guint page_num; + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (container)); g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - - notebook = GTK_NOTEBOOK (widget); - GTK_WIDGET_SET_FLAGS (notebook, GTK_REALIZED); - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x; - attributes.y = widget->allocation.y; - attributes.width = widget->allocation.width; - attributes.height = widget->allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, notebook); - widget->style = gtk_style_attach (widget->style, widget->window); - gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); + notebook = GTK_NOTEBOOK (container); - gdk_window_set_back_pixmap (widget->window, NULL, TRUE); - if (notebook->scrollable) - gtk_notebook_panel_realize (notebook); + children = notebook->children; + page_num = 0; + while (children) + { + page = children->data; + if (page->child == widget) + { + gtk_notebook_real_remove (notebook, children); + break; + } + page_num++; + children = children->next; + } } -static void -gtk_notebook_panel_realize (GtkNotebook *notebook) +static gint +gtk_notebook_focus (GtkContainer *container, + GtkDirectionType direction) { - GtkWidget *widget; - GdkWindowAttr attributes; - gint attributes_mask; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - widget = GTK_WIDGET (notebook); - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK - | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - attributes.width = 2 * ARROW_SIZE + ARROW_SPACING; - attributes.height = ARROW_SIZE; - - attributes.x = widget->allocation.width - attributes.width - - GTK_CONTAINER (notebook)->border_width; - attributes.y = widget->allocation.height - ARROW_SIZE - - GTK_CONTAINER (notebook)->border_width; - if (notebook->tab_pos == GTK_POS_TOP) - attributes.y = GTK_CONTAINER (notebook)->border_width; - else if (notebook->tab_pos == GTK_POS_LEFT) - attributes.x = widget->allocation.x - + GTK_CONTAINER (notebook)->border_width; + GtkNotebook *notebook; + GtkWidget *focus_child; + GtkNotebookPage *page = NULL; + GtkNotebookPage *old_page = NULL; - - notebook->panel = gdk_window_new (widget->window, &attributes, - attributes_mask); - gtk_style_set_background (widget->style, notebook->panel, - GTK_STATE_NORMAL); - gdk_window_set_back_pixmap (widget->window, NULL, TRUE); - gdk_window_set_user_data (notebook->panel, widget); -} + g_return_val_if_fail (container != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (container), FALSE); -static void -gtk_notebook_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - GtkNotebook *notebook; - GtkNotebookPage *page; - GList *children; + notebook = GTK_NOTEBOOK (container); - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - g_return_if_fail (requisition != NULL); + if (!GTK_WIDGET_DRAWABLE (notebook) || !GTK_WIDGET_SENSITIVE (container) || + !notebook->children || !notebook->cur_page) + return FALSE; - notebook = GTK_NOTEBOOK (widget); - widget->requisition.width = 0; - widget->requisition.height = 0; + focus_child = container->focus_child; + gtk_container_set_focus_child (container, NULL); - children = notebook->children; - while (children) + if (!notebook->show_tabs) { - page = children->data; - children = children->next; - - if (GTK_WIDGET_VISIBLE (page->child)) + if (GTK_WIDGET_DRAWABLE (notebook->cur_page->child) && + GTK_WIDGET_SENSITIVE (notebook->cur_page->child)) { - gtk_widget_size_request (page->child, &page->child->requisition); - - widget->requisition.width = MAX (widget->requisition.width, - page->child->requisition.width); - widget->requisition.height = MAX (widget->requisition.height, - page->child->requisition.height); + if (GTK_IS_CONTAINER (notebook->cur_page->child)) + { + if (gtk_container_focus + (GTK_CONTAINER (notebook->cur_page->child), direction)) + return TRUE; + } + else if (GTK_WIDGET_CAN_FOCUS (notebook->cur_page->child)) + { + if (!focus_child) + { + gtk_widget_grab_focus (notebook->cur_page->child); + return TRUE; + } + } } + return FALSE; } - if (notebook->show_border || notebook->show_tabs) - { - widget->requisition.width += widget->style->klass->xthickness * 2; - widget->requisition.height += widget->style->klass->ythickness * 2; + if (notebook->focus_tab) + old_page = notebook->focus_tab->data; - if (notebook->show_tabs) + if (focus_child && old_page && focus_child == old_page->child && + notebook->child_has_focus) + { + if (GTK_WIDGET_DRAWABLE (old_page->child)) { - gint tab_width = 0; - gint tab_height = 0; - gint tab_max = 0; - - children = notebook->children; - while (children) + if (GTK_IS_CONTAINER (old_page->child) && + !GTK_WIDGET_HAS_FOCUS (old_page->child)) { - page = children->data; - children = children->next; - - if (GTK_WIDGET_VISIBLE (page->child)) - { - gtk_widget_size_request (page->tab_label, - &page->tab_label->requisition); - - page->requisition.width = - (page->tab_label->requisition.width + - (widget->style->klass->xthickness + notebook->tab_border) - * 2); - page->requisition.height = - (page->tab_label->requisition.height + - (widget->style->klass->ythickness + notebook->tab_border) - * 2); - - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - case GTK_POS_BOTTOM: - page->requisition.width -= TAB_OVERLAP; + if (gtk_container_focus (GTK_CONTAINER (old_page->child), + direction)) + return TRUE; + } + gtk_widget_grab_focus (GTK_WIDGET(notebook)); + return TRUE; + } + return FALSE; + } - tab_width += page->requisition.width; - tab_height = MAX (tab_height, page->requisition.height); - tab_max = MAX (tab_max, page->requisition.width); - break; - case GTK_POS_LEFT: - case GTK_POS_RIGHT: - page->requisition.height -= TAB_OVERLAP; + switch (direction) + { + case GTK_DIR_TAB_FORWARD: + case GTK_DIR_RIGHT: + case GTK_DIR_DOWN: + gtk_notebook_switch_focus_tab + (notebook, gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_NEXT, TRUE)); + break; + case GTK_DIR_TAB_BACKWARD: + case GTK_DIR_LEFT: + case GTK_DIR_UP: + gtk_notebook_switch_focus_tab + (notebook, gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_PREV, TRUE)); + break; + } - tab_width = MAX (tab_width, page->requisition.width); - tab_height += page->requisition.height; - tab_max = MAX (tab_max, page->requisition.height); - break; - } - } - } + if (notebook->focus_tab) + { + if (!GTK_WIDGET_HAS_FOCUS (container)) + gtk_widget_grab_focus (GTK_WIDGET (container)); - children = notebook->children; + page = notebook->focus_tab->data; + if (GTK_WIDGET_MAPPED (page->tab_label)) + gtk_notebook_focus_changed (notebook, old_page); + else + { + gtk_notebook_pages_allocate (notebook, + &(GTK_WIDGET (notebook)->allocation)); + gtk_notebook_expose_tabs (notebook); + } + return TRUE; + } - if (children && children->next && notebook->scrollable) - { - if ((notebook->tab_pos == GTK_POS_TOP) || - (notebook->tab_pos == GTK_POS_BOTTOM)) - { - if (widget->requisition.width < tab_width) - { - tab_width = tab_max + 2 * (ARROW_SIZE + ARROW_SPACING); - tab_height = MAX (tab_height, ARROW_SIZE); - } - } - else - { - if (widget->requisition.height < tab_height) - { - tab_height = tab_max + ARROW_SIZE + ARROW_SPACING; - tab_width = MAX (tab_width, - ARROW_SPACING + 2 * ARROW_SIZE); - } - } - } + gtk_notebook_focus_changed (notebook, old_page); + return FALSE; +} + +static void +gtk_notebook_set_focus_child (GtkContainer *container, + GtkWidget *child) +{ + GtkNotebook *notebook; + + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (container)); + + if (child) + { + g_return_if_fail (GTK_IS_WIDGET (child)); + + notebook = GTK_NOTEBOOK (container); + + notebook->child_has_focus = TRUE; + if (!notebook->focus_tab) + { + GList *children; + GtkNotebookPage *page; + children = notebook->children; while (children) { page = children->data; + if (page->child == child || page->tab_label == child) + gtk_notebook_switch_focus_tab (notebook, children); children = children->next; - - if (GTK_WIDGET_VISIBLE (page->child)) - { - if ((notebook->tab_pos == GTK_POS_TOP) || - (notebook->tab_pos == GTK_POS_BOTTOM)) - page->requisition.height = tab_height; - else - page->requisition.width = tab_width; - } - } - - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - case GTK_POS_BOTTOM: - tab_width += widget->style->klass->xthickness; - widget->requisition.width = MAX (widget->requisition.width, - tab_width); - widget->requisition.height += tab_height; - break; - case GTK_POS_LEFT: - case GTK_POS_RIGHT: - tab_height += widget->style->klass->ythickness; - widget->requisition.width += tab_width; - widget->requisition.height = MAX (widget->requisition.height, - tab_height); - break; } } } - widget->requisition.width += GTK_CONTAINER (widget)->border_width * 2; - widget->requisition.height += GTK_CONTAINER (widget)->border_width * 2; + parent_class->set_focus_child (container, child); } static void -gtk_notebook_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) +gtk_notebook_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) { GtkNotebook *notebook; - GtkNotebookPage *page; - GtkAllocation child_allocation; GList *children; - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - g_return_if_fail (allocation != NULL); + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (container)); + g_return_if_fail (callback != NULL); - widget->allocation = *allocation; - if (GTK_WIDGET_REALIZED (widget)) - gdk_window_move_resize (widget->window, - allocation->x, allocation->y, - allocation->width, allocation->height); + notebook = GTK_NOTEBOOK (container); - notebook = GTK_NOTEBOOK (widget); - if (notebook->children) + children = notebook->children; + while (children) { - child_allocation.x = GTK_CONTAINER (widget)->border_width; - child_allocation.y = GTK_CONTAINER (widget)->border_width; - child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2); - child_allocation.height = MAX (1, allocation->height - child_allocation.y * 2); - - if (notebook->show_tabs || notebook->show_border) + GtkNotebookPage *page; + + page = children->data; + children = children->next; + (* callback) (page->child, callback_data); + if (include_internals) { - child_allocation.x += widget->style->klass->xthickness; - child_allocation.y += widget->style->klass->ythickness; - child_allocation.width = MAX (1, - child_allocation.width - widget->style->klass->xthickness * 2); - child_allocation.height = MAX (1, - child_allocation.height - widget->style->klass->ythickness * 2); - - if (notebook->show_tabs && notebook->children) - { - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - child_allocation.y += notebook->cur_page->requisition.height; - case GTK_POS_BOTTOM: - child_allocation.height = MAX (1, - child_allocation.height - notebook->cur_page->requisition.height); - break; - case GTK_POS_LEFT: - child_allocation.x += notebook->cur_page->requisition.width; - case GTK_POS_RIGHT: - child_allocation.width = MAX (1, - child_allocation.width - notebook->cur_page->requisition.width); - break; - } - } + if (page->tab_label) + (* callback) (page->tab_label, callback_data); + if (page->menu_label) + (* callback) (page->menu_label, callback_data); } + } +} - children = notebook->children; - while (children) - { - page = children->data; - children = children->next; - - if (GTK_WIDGET_VISIBLE (page->child)) - gtk_widget_size_allocate (page->child, &child_allocation); - } +static GtkType +gtk_notebook_child_type (GtkContainer *container) +{ + return GTK_TYPE_WIDGET; +} - gtk_notebook_pages_allocate (notebook, allocation); - } - gtk_notebook_set_shape (notebook); +/* Private GtkNotebook Functions: + * + * gtk_notebook_panel_realize + * gtk_notebook_expose_tabs + * gtk_notebook_focus_changed + * gtk_notebook_real_remove + * gtk_notebook_update_labels + * gtk_notebook_timer + * gtk_notebook_page_compare + * gtk_notebook_real_page_position + * gtk_notebook_search_page + */ +static void +gtk_notebook_panel_realize (GtkNotebook *notebook) +{ + GtkWidget *widget; + GdkWindowAttr attributes; + gint attributes_mask; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + widget = GTK_WIDGET (notebook); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.event_mask = gtk_widget_get_events (widget); + attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK + | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + + attributes.width = 2 * ARROW_SIZE + ARROW_SPACING; + attributes.height = ARROW_SIZE; + + attributes.x = (widget->allocation.width - attributes.width - + GTK_CONTAINER (notebook)->border_width); + attributes.y = (widget->allocation.height - ARROW_SIZE - + GTK_CONTAINER (notebook)->border_width); + if (notebook->tab_pos == GTK_POS_TOP) + attributes.y = GTK_CONTAINER (notebook)->border_width; + else if (notebook->tab_pos == GTK_POS_LEFT) + attributes.x = (widget->allocation.x + + GTK_CONTAINER (notebook)->border_width); + + notebook->panel = gdk_window_new (widget->window, &attributes, + attributes_mask); + gtk_style_set_background (widget->style, notebook->panel, + GTK_STATE_NORMAL); + gdk_window_set_back_pixmap (widget->window, NULL, TRUE); + gdk_window_set_user_data (notebook->panel, widget); } static void -gtk_notebook_paint (GtkWidget *widget, - GdkRectangle *area) +gtk_notebook_expose_tabs (GtkNotebook *notebook) { - GtkNotebook *notebook; + GtkWidget *widget; GtkNotebookPage *page; - GList *children; - gint width, height; - gint x, y; - gint showarrow; - gint gap_x = 0, gap_width = 0; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - g_return_if_fail (area != NULL); + GdkEventExpose event; + gint border; - if (GTK_WIDGET_DRAWABLE (widget)) - { - notebook = GTK_NOTEBOOK (widget); + widget = GTK_WIDGET (notebook); + border = GTK_CONTAINER (notebook)->border_width; - if (notebook->show_tabs || notebook->show_border) - { - x = GTK_CONTAINER (widget)->border_width; - y = GTK_CONTAINER (widget)->border_width; - width = widget->allocation.width - x * 2; - height = widget->allocation.height - y * 2; + if (!GTK_WIDGET_MAPPED (notebook) || !notebook->first_tab) + return; - if (notebook->show_tabs && notebook->children) - { + page = notebook->first_tab->data; - if (!GTK_WIDGET_MAPPED (notebook->cur_page->tab_label)) - { - GtkNotebookPage *page; + event.type = GDK_EXPOSE; + event.window = widget->window; + event.count = 0; + event.area.x = border; + event.area.y = border; - page = notebook->first_tab->data; - - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - y += page->allocation.height + - widget->style->klass->ythickness; - case GTK_POS_BOTTOM: - height -= page->allocation.height + - widget->style->klass->ythickness; - break; - case GTK_POS_LEFT: - x += page->allocation.width + - widget->style->klass->xthickness; - case GTK_POS_RIGHT: - width -= page->allocation.width + - widget->style->klass->xthickness; - break; - } - gtk_paint_box (widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - area, widget, "notebook", - x, y, width, height); - } - else - { - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - y += notebook->cur_page->allocation.height; - case GTK_POS_BOTTOM: - height -= notebook->cur_page->allocation.height; - break; - case GTK_POS_LEFT: - x += notebook->cur_page->allocation.width; - case GTK_POS_RIGHT: - width -= notebook->cur_page->allocation.width; - break; - } + switch (notebook->tab_pos) + { + case GTK_POS_BOTTOM: + event.area.y = (widget->allocation.height - border - + page->allocation.height - + widget->style->klass->ythickness); + if (page != notebook->cur_page) + event.area.y -= widget->style->klass->ythickness; + case GTK_POS_TOP: + event.area.width = widget->allocation.width - 2 * border; + event.area.height = (page->allocation.height + + widget->style->klass->ythickness); + if (page != notebook->cur_page) + event.area.height += widget->style->klass->ythickness; + break; + case GTK_POS_RIGHT: + event.area.x = (widget->allocation.width - border - + page->allocation.width - + widget->style->klass->xthickness); + if (page != notebook->cur_page) + event.area.x -= widget->style->klass->xthickness; + case GTK_POS_LEFT: + event.area.width = (page->allocation.width + + widget->style->klass->xthickness); + event.area.height = widget->allocation.height - 2 * border; + if (page != notebook->cur_page) + event.area.width += widget->style->klass->xthickness; + break; + } + gtk_widget_event (widget, (GdkEvent *) &event); +} - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - gap_x = notebook->cur_page->allocation.x - - GTK_CONTAINER(notebook)->border_width; - gap_width = notebook->cur_page->allocation.width; - break; - case GTK_POS_BOTTOM: - gap_x = notebook->cur_page->allocation.x - - GTK_CONTAINER(notebook)->border_width; - gap_width = notebook->cur_page->allocation.width; - break; - case GTK_POS_LEFT: - gap_x = notebook->cur_page->allocation.y - - GTK_CONTAINER(notebook)->border_width; - gap_width = notebook->cur_page->allocation.height; - break; - case GTK_POS_RIGHT: - gap_x = notebook->cur_page->allocation.y - - GTK_CONTAINER(notebook)->border_width; - gap_width = notebook->cur_page->allocation.height; - break; - } - gtk_paint_box_gap(widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - area, widget, "notebook", - x, y, width, height, - notebook->tab_pos, gap_x, gap_width); - } - children = g_list_last (notebook->children); - showarrow = FALSE; +static void +gtk_notebook_focus_changed (GtkNotebook *notebook, + GtkNotebookPage *old_page) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - while (children) - { - page = children->data; - children = children->prev; + gtk_notebook_expose_tabs(notebook); +} - if (!GTK_WIDGET_MAPPED (page->tab_label)) - showarrow = TRUE; - else if (notebook->cur_page != page) - gtk_notebook_draw_tab (notebook, page, area); - } +static gint +gtk_notebook_timer (GtkNotebook *notebook) +{ + g_return_val_if_fail (notebook != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE); - if (showarrow && notebook->scrollable && notebook->show_tabs) - { - gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); - } - if (notebook->cur_page && - GTK_WIDGET_MAPPED(((GtkNotebookPage *) - (notebook->cur_page))->tab_label)) - gtk_notebook_draw_tab (notebook, notebook->cur_page, area); - } - else if (notebook->show_border) - { - gtk_paint_box(widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - area, widget, "notebook", - x, y, width, height); - } + if (notebook->timer) + { + if (notebook->click_child == GTK_ARROW_LEFT) + { + if (!notebook->focus_tab || + gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_PREV, TRUE)) + gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT); + } + else if (notebook->click_child == GTK_ARROW_RIGHT) + { + if (!notebook->focus_tab || + gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_NEXT, TRUE)) + gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_RIGHT); + } + if (notebook->need_timer) + { + notebook->need_timer = FALSE; + notebook->timer = gtk_timeout_add (NOTEBOOK_SCROLL_DELAY, + (GtkFunction) gtk_notebook_timer, + (gpointer) notebook); + return FALSE; } + return TRUE; } + return FALSE; +} + +static gint +gtk_notebook_page_compare (gconstpointer a, + gconstpointer b) +{ + return (((GtkNotebookPage *) a)->child != b); } static void -gtk_notebook_draw (GtkWidget *widget, - GdkRectangle *area) +gtk_notebook_real_remove (GtkNotebook *notebook, + GList *list) { - GtkNotebook *notebook; - GdkRectangle child_area; + GtkNotebookPage *page; + GList * next_list; + gint need_resize = FALSE; - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - g_return_if_fail (area != NULL); + next_list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE); + if (!next_list) + next_list = gtk_notebook_search_page (notebook, list, STEP_NEXT, TRUE); - if (GTK_WIDGET_DRAWABLE (widget)) - { - notebook = GTK_NOTEBOOK (widget); + if (notebook->cur_page == list->data) + { + notebook->cur_page = NULL; + if (next_list) + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next_list), -1); + } - gtk_notebook_paint (widget, area); - gtk_widget_draw_focus (widget); + if (list == notebook->first_tab) + notebook->first_tab = next_list; + if (list == notebook->focus_tab) + gtk_notebook_switch_focus_tab (notebook, next_list); - if (notebook->cur_page && - gtk_widget_intersect (notebook->cur_page->child, area, &child_area)) - gtk_widget_draw (notebook->cur_page->child, &child_area); - } -} + page = list->data; -static gint -gtk_notebook_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - GtkNotebook *notebook; - GdkEventExpose child_event; - GdkRectangle child_area; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); + if (GTK_WIDGET_VISIBLE (page->child) && GTK_WIDGET_VISIBLE (notebook)) + need_resize = TRUE; - if (GTK_WIDGET_DRAWABLE (widget)) - { - notebook = GTK_NOTEBOOK (widget); + gtk_widget_unparent (page->child); - gtk_notebook_paint (widget, &event->area); - if (notebook->cur_page && - gtk_widget_intersect (notebook->cur_page->tab_label, - &event->area, &child_area)) - gtk_widget_draw_focus (widget); + if (page->tab_label) + gtk_widget_unparent (page->tab_label); - child_event = *event; - if (notebook->cur_page && - GTK_WIDGET_NO_WINDOW (notebook->cur_page->child) && - gtk_widget_intersect (notebook->cur_page->child, &event->area, - &child_event.area)) - gtk_widget_event (notebook->cur_page->child, (GdkEvent*) &child_event); + if (notebook->menu) + { + gtk_container_remove (GTK_CONTAINER (notebook->menu), + page->menu_label->parent); + gtk_widget_queue_resize (notebook->menu); } + if (!page->default_menu) + gtk_widget_unref (page->menu_label); + + notebook->children = g_list_remove_link (notebook->children, list); + g_list_free (list); + g_free (page); - return FALSE; + gtk_notebook_update_labels (notebook); + if (need_resize) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); } -static gint -gtk_notebook_button_press (GtkWidget *widget, - GdkEventButton *event) +static void +gtk_notebook_update_labels (GtkNotebook *notebook) { - GtkNotebook *notebook; GtkNotebookPage *page; - GList *children; - gint num; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - notebook = GTK_NOTEBOOK (widget); - - if (event->type != GDK_BUTTON_PRESS || !notebook->children - || notebook->button) - return FALSE; + GList *list; + gchar string[32]; + gint page_num = 1; - if (event->window == notebook->panel) + for (list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, FALSE); + list; + list = gtk_notebook_search_page (notebook, list, STEP_NEXT, FALSE)) { - if (!GTK_WIDGET_HAS_FOCUS (widget)) - gtk_widget_grab_focus (widget); - - gtk_grab_add (widget); - notebook->button = event->button; - - if (event->x <= ARROW_SIZE + ARROW_SPACING / 2) + page = list->data; + sprintf (string, "Page %u", page_num++); + if (notebook->show_tabs) { - notebook->click_child = GTK_ARROW_LEFT; - if (event->button == 1) + if (page->default_tab) { - if (!notebook->focus_tab || notebook->focus_tab->prev) - gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT); - - if (!notebook->timer) + if (!page->tab_label) { - notebook->timer = gtk_timeout_add - (NOTEBOOK_INIT_SCROLL_DELAY, - (GtkFunction) gtk_notebook_timer, (gpointer) notebook); - notebook->need_timer = TRUE; + page->tab_label = gtk_label_new (string); + gtk_widget_set_parent (page->tab_label, + GTK_WIDGET (notebook)); } + else + gtk_label_set (GTK_LABEL (page->tab_label), string); } - else if (event->button == 2) - gtk_notebook_page_select (GTK_NOTEBOOK (widget)); - else if (event->button == 3) - gtk_notebook_switch_focus_tab (notebook, notebook->children); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + + if (GTK_WIDGET_VISIBLE (page->child) && + !GTK_WIDGET_VISIBLE (page->tab_label)) + gtk_widget_show (page->tab_label); + else if (!GTK_WIDGET_VISIBLE (page->child) && + GTK_WIDGET_VISIBLE (page->tab_label)) + gtk_widget_hide (page->tab_label); } - else + if (notebook->menu && page->default_menu) { - notebook->click_child = GTK_ARROW_RIGHT; - if (event->button == 1) - { - if (!notebook->focus_tab || notebook->focus_tab->next) - gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_RIGHT); - if (!notebook->timer) - { - notebook->timer = gtk_timeout_add - (NOTEBOOK_INIT_SCROLL_DELAY, - (GtkFunction) gtk_notebook_timer, (gpointer) notebook); - notebook->need_timer = TRUE; - } - } - else if (event->button == 2) - gtk_notebook_page_select (GTK_NOTEBOOK (widget)); - else if (event->button == 3) - gtk_notebook_switch_focus_tab (notebook, - g_list_last (notebook->children)); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + if (page->tab_label && GTK_IS_LABEL (page->tab_label)) + gtk_label_set (GTK_LABEL (page->menu_label), + GTK_LABEL (page->tab_label)->label); + else + gtk_label_set (GTK_LABEL (page->menu_label), string); } + } +} + +static gint +gtk_notebook_real_page_position (GtkNotebook *notebook, + GList *list) +{ + GList *work; + gint count_start; + + g_return_val_if_fail (notebook != NULL, -1); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); + g_return_val_if_fail (list != NULL, -1); + + for (work = notebook->children, count_start = 0; + work && work != list; work = work->next) + if (GTK_NOTEBOOK_PAGE (work)->pack == GTK_PACK_START) + count_start++; + + if (!work) + return -1; + + if (GTK_NOTEBOOK_PAGE (list)->pack == GTK_PACK_START) + return count_start; + + return (count_start + g_list_length (list) - 1); +} + +static GList * +gtk_notebook_search_page (GtkNotebook *notebook, + GList *list, + gint direction, + gboolean find_visible) +{ + GtkNotebookPage *page = NULL; + GList *old_list = NULL; + gint flag = 0; + + g_return_val_if_fail (notebook != NULL, NULL); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); + + switch (direction) + { + case STEP_PREV: + flag = GTK_PACK_END; + break; + + case STEP_NEXT: + flag = GTK_PACK_START; + break; } - else if (event->window == widget->window) + + if (list) + page = list->data; + + if (!page || page->pack == flag) { - if (event->button == 3 && notebook->menu) + if (list) { - gtk_menu_popup (GTK_MENU (notebook->menu), NULL, NULL, - NULL, NULL, 3, event->time); - return FALSE; + old_list = list; + list = list->next; } + else + list = notebook->children; - num = 0; - children = notebook->children; - while (children) + while (list) { - page = children->data; - - if (GTK_WIDGET_VISIBLE (page->child) && - page->tab_label && GTK_WIDGET_MAPPED (page->tab_label) && - (event->x >= page->allocation.x) && - (event->y >= page->allocation.y) && - (event->x <= (page->allocation.x + page->allocation.width)) && - (event->y <= (page->allocation.y + page->allocation.height))) - { - if (page == notebook->cur_page && notebook->focus_tab && - notebook->focus_tab != children && - GTK_WIDGET_HAS_FOCUS (notebook)) - { - GtkNotebookPage *old_page; - - notebook->child_has_focus = FALSE; - old_page = (GtkNotebookPage *) - (notebook->focus_tab->data); - gtk_notebook_switch_focus_tab (notebook, children); - gtk_notebook_focus_changed (notebook, old_page); - } - else - { - gtk_notebook_switch_focus_tab (notebook, children); - gtk_notebook_switch_page (notebook, page, num); - gtk_widget_grab_focus (widget); - } - break; - } - children = children->next; - num++; + page = list->data; + if (page->pack == flag && + (!find_visible || GTK_WIDGET_VISIBLE (page->child))) + return list; + old_list = list; + list = list->next; } - if (!children && !GTK_WIDGET_HAS_FOCUS (widget)) - gtk_widget_grab_focus (widget); + list = old_list; } - gtk_notebook_set_shape (notebook); - return FALSE; + else + { + old_list = list; + list = list->prev; + } + while (list) + { + page = list->data; + if (page->pack != flag && + (!find_visible || GTK_WIDGET_VISIBLE (page->child))) + return list; + old_list = list; + list = list->prev; + } + return NULL; } -static gint -gtk_notebook_button_release (GtkWidget *widget, - GdkEventButton *event) +/* Private GtkNotebook Drawing Functions: + * + * gtk_notebook_paint + * gtk_notebook_draw_tab + * gtk_notebook_draw_arrow + * gtk_notebook_set_shape + */ +static void +gtk_notebook_paint (GtkWidget *widget, + GdkRectangle *area) { GtkNotebook *notebook; + GtkNotebookPage *page; + GList *children; + gboolean showarrow; + gint width, height; + gint x, y; + gint gap_x = 0, gap_width = 0; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + g_return_if_fail (area != NULL); - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - if (event->type != GDK_BUTTON_RELEASE) - return FALSE; + if (!GTK_WIDGET_DRAWABLE (widget)) + return; notebook = GTK_NOTEBOOK (widget); - if (event->button == notebook->button) + if ((!notebook->show_tabs && !notebook->show_border) || + !notebook->cur_page || !GTK_WIDGET_VISIBLE (notebook->cur_page->child)) { - guint click_child; - - if (notebook->timer) - { - gtk_timeout_remove (notebook->timer); - notebook->timer = 0; - notebook->need_timer = FALSE; - } - gtk_grab_remove (widget); - click_child = notebook->click_child; - notebook->click_child = 0; - notebook->button = 0; - gtk_notebook_draw_arrow (notebook, click_child); - + gdk_window_clear_area (widget->window, + area->x, area->y, + area->width, area->height); + return; } - return FALSE; -} -static gint -gtk_notebook_enter_notify (GtkWidget *widget, - GdkEventCrossing *event) -{ - GtkNotebook *notebook; + x = GTK_CONTAINER (widget)->border_width; + y = GTK_CONTAINER (widget)->border_width; + width = widget->allocation.width - x * 2; + height = widget->allocation.height - y * 2; - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); + if (notebook->show_border && (!notebook->show_tabs || !notebook->children)) + { + + gtk_paint_box(widget->style, widget->window, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, + area, widget, "notebook", + x, y, width, height); + return; + } - notebook = GTK_NOTEBOOK (widget); - if (event->window == notebook->panel) + if (!GTK_WIDGET_MAPPED (notebook->cur_page->tab_label)) { - gint x; - gint y; + page = notebook->first_tab->data; - gdk_window_get_pointer (notebook->panel, &x, &y, NULL); - - if (x <= ARROW_SIZE + ARROW_SPACING / 2) + switch (notebook->tab_pos) { - notebook->in_child = GTK_ARROW_LEFT; - - if (notebook->click_child == 0) - gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + case GTK_POS_TOP: + y += page->allocation.height + widget->style->klass->ythickness; + case GTK_POS_BOTTOM: + height -= page->allocation.height + widget->style->klass->ythickness; + break; + case GTK_POS_LEFT: + x += page->allocation.width + widget->style->klass->xthickness; + case GTK_POS_RIGHT: + width -= page->allocation.width + widget->style->klass->xthickness; + break; } - else + gtk_paint_box (widget->style, widget->window, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, + area, widget, "notebook", + x, y, width, height); + } + else + { + switch (notebook->tab_pos) { - notebook->in_child = GTK_ARROW_RIGHT; + case GTK_POS_TOP: + y += notebook->cur_page->allocation.height; + case GTK_POS_BOTTOM: + height -= notebook->cur_page->allocation.height; + break; + case GTK_POS_LEFT: + x += notebook->cur_page->allocation.width; + case GTK_POS_RIGHT: + width -= notebook->cur_page->allocation.width; + break; + } - if (notebook->click_child == 0) - gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + gap_x = (notebook->cur_page->allocation.x - + GTK_CONTAINER(notebook)->border_width); + gap_width = notebook->cur_page->allocation.width; + break; + case GTK_POS_BOTTOM: + gap_x = (notebook->cur_page->allocation.x - + GTK_CONTAINER(notebook)->border_width); + gap_width = notebook->cur_page->allocation.width; + break; + case GTK_POS_LEFT: + gap_x = (notebook->cur_page->allocation.y - + GTK_CONTAINER(notebook)->border_width); + gap_width = notebook->cur_page->allocation.height; + break; + case GTK_POS_RIGHT: + gap_x = (notebook->cur_page->allocation.y - + GTK_CONTAINER(notebook)->border_width); + gap_width = notebook->cur_page->allocation.height; + break; } + gtk_paint_box_gap(widget->style, widget->window, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, + area, widget, "notebook", + x, y, width, height, + notebook->tab_pos, gap_x, gap_width); } - return FALSE; + showarrow = FALSE; + children = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE); + while (children) + { + page = children->data; + children = gtk_notebook_search_page (notebook, children, + STEP_PREV, TRUE); + if (!GTK_WIDGET_VISIBLE (page->child)) + continue; + if (!GTK_WIDGET_MAPPED (page->tab_label)) + showarrow = TRUE; + else if (page != notebook->cur_page) + gtk_notebook_draw_tab (notebook, page, area); + } + + if (showarrow && notebook->scrollable) + { + gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + } + gtk_notebook_draw_tab (notebook, notebook->cur_page, area); } -static gint -gtk_notebook_leave_notify (GtkWidget *widget, - GdkEventCrossing *event) +static void +gtk_notebook_draw_tab (GtkNotebook *notebook, + GtkNotebookPage *page, + GdkRectangle *area) { - GtkNotebook *notebook; + GdkRectangle child_area; + GdkRectangle page_area; + GtkStateType state_type; + GtkPositionType gap_side; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (page != NULL); + g_return_if_fail (area != NULL); - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); + if (!GTK_WIDGET_MAPPED (page->tab_label) || + (page->allocation.width == 0) || (page->allocation.height == 0)) + return; - notebook = GTK_NOTEBOOK (widget); + page_area.x = page->allocation.x; + page_area.y = page->allocation.y; + page_area.width = page->allocation.width; + page_area.height = page->allocation.height; - if (event->window == notebook->panel && !notebook->click_child) + if (gdk_rectangle_intersect (&page_area, area, &child_area)) { - if (notebook->in_child == GTK_ARROW_LEFT) + GtkWidget *widget; + + widget = GTK_WIDGET (notebook); + gap_side = 0; + switch (notebook->tab_pos) { - notebook->in_child = 0; - gtk_notebook_draw_arrow (notebook,GTK_ARROW_LEFT); + case GTK_POS_TOP: + gap_side = GTK_POS_BOTTOM; + break; + case GTK_POS_BOTTOM: + gap_side = GTK_POS_TOP; + break; + case GTK_POS_LEFT: + gap_side = GTK_POS_RIGHT; + break; + case GTK_POS_RIGHT: + gap_side = GTK_POS_LEFT; + break; } - else + + if (notebook->cur_page == page) + state_type = GTK_STATE_NORMAL; + else + state_type = GTK_STATE_ACTIVE; + gtk_paint_extension(widget->style, widget->window, + state_type, GTK_SHADOW_OUT, + area, widget, "tab", + page_area.x, page_area.y, + page_area.width, page_area.height, + gap_side); + if ((GTK_WIDGET_HAS_FOCUS (widget)) && + notebook->focus_tab && (notebook->focus_tab->data == page) && + (page)) { - notebook->in_child = 0; - gtk_notebook_draw_arrow (notebook,GTK_ARROW_RIGHT); + gtk_paint_focus (widget->style, widget->window, + area, widget, "tab", + page->tab_label->allocation.x - 1, + page->tab_label->allocation.y - 1, + page->tab_label->allocation.width + 1, + page->tab_label->allocation.height + 1); } + if (gtk_widget_intersect (page->tab_label, area, &child_area)) + gtk_widget_draw (page->tab_label, &child_area); } - return FALSE; } -static gint -gtk_notebook_motion_notify (GtkWidget *widget, - GdkEventMotion *event) +static void +gtk_notebook_draw_arrow (GtkNotebook *notebook, + guint arrow) { - GtkNotebook *notebook; + GtkStateType state_type; + GtkShadowType shadow_type; + GtkWidget *widget; - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - notebook = GTK_NOTEBOOK (widget); - - if (notebook->button) - return FALSE; + widget = GTK_WIDGET(notebook); - if (event->window == notebook->panel) - { - gint x; - - x = event->x; - if (event->is_hint) - gdk_window_get_pointer (notebook->panel, &x, NULL, NULL); - - if (x <= ARROW_SIZE + ARROW_SPACING / 2 && - notebook->in_child == GTK_ARROW_RIGHT) - { - notebook->in_child = GTK_ARROW_LEFT; - gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); - } - else if (x > ARROW_SIZE + ARROW_SPACING / 2 && - notebook->in_child == GTK_ARROW_LEFT) - { - notebook->in_child = GTK_ARROW_RIGHT; - gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); - } - return FALSE; - } - return FALSE; -} - -static gint -gtk_notebook_timer (GtkNotebook *notebook) -{ - g_return_val_if_fail (notebook != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE); - - if (notebook->timer) - { - if (notebook->click_child == GTK_ARROW_LEFT) - { - if (!notebook->focus_tab || notebook->focus_tab->prev) - gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT); - } - else if (notebook->click_child == GTK_ARROW_RIGHT) - { - if (!notebook->focus_tab || notebook->focus_tab->next) - gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_RIGHT); - } - - if (notebook->need_timer) - { - notebook->need_timer = FALSE; - notebook->timer = gtk_timeout_add - (NOTEBOOK_SCROLL_DELAY, (GtkFunction) gtk_notebook_timer, - (gpointer) notebook); - return FALSE; - } - return TRUE; - } - return FALSE; -} - -static void -gtk_notebook_draw_arrow (GtkNotebook *notebook, guint arrow) -{ - GtkStateType state_type; - GtkShadowType shadow_type; - GtkWidget *widget; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - widget = GTK_WIDGET(notebook); - - if (GTK_WIDGET_DRAWABLE (notebook)) + if (GTK_WIDGET_DRAWABLE (notebook)) { if (notebook->in_child == arrow) { @@ -2176,7 +2282,9 @@ gtk_notebook_draw_arrow (GtkNotebook *notebook, guint arrow) if (arrow == GTK_ARROW_LEFT) { - if (notebook->focus_tab && !notebook->focus_tab->prev) + if (notebook->focus_tab && + !gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_PREV, TRUE)) { shadow_type = GTK_SHADOW_ETCHED_IN; state_type = GTK_STATE_NORMAL; @@ -2194,7 +2302,9 @@ gtk_notebook_draw_arrow (GtkNotebook *notebook, guint arrow) } else { - if (notebook->focus_tab && !notebook->focus_tab->next) + if (notebook->focus_tab && + !gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_NEXT, TRUE)) { shadow_type = GTK_SHADOW_ETCHED_IN; state_type = GTK_STATE_NORMAL; @@ -2203,6 +2313,7 @@ gtk_notebook_draw_arrow (GtkNotebook *notebook, guint arrow) if (notebook->tab_pos == GTK_POS_LEFT || notebook->tab_pos == GTK_POS_RIGHT) arrow = GTK_ARROW_DOWN; + gdk_window_clear_area(notebook->panel, ARROW_SIZE + ARROW_SPACING, 0, ARROW_SIZE, ARROW_SIZE); gtk_paint_arrow (widget->style, notebook->panel, state_type, @@ -2214,333 +2325,679 @@ gtk_notebook_draw_arrow (GtkNotebook *notebook, guint arrow) } static void -gtk_notebook_real_switch_page (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num) +gtk_notebook_set_shape (GtkNotebook *notebook) { - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (page != NULL); + GtkWidget *widget = NULL; + GdkPixmap *pm = NULL; + GdkGC *pmgc = NULL; + GdkColor col; + gint x, y, width, height, w, h, depth; + GtkNotebookPage *page; + GList *children; - if (notebook->cur_page == page) + if (!GTK_WIDGET(notebook)->window) return; - if (notebook->cur_page && GTK_WIDGET_MAPPED (notebook->cur_page->child)) - gtk_widget_unmap (notebook->cur_page->child); - - notebook->cur_page = page; + widget = GTK_WIDGET(notebook); - if (!notebook->focus_tab || - notebook->focus_tab->data != (gpointer) notebook->cur_page) - notebook->focus_tab = - g_list_find (notebook->children, notebook->cur_page); + w = widget->allocation.width; + h = widget->allocation.height; - gtk_notebook_pages_allocate (notebook, >K_WIDGET (notebook)->allocation); - - if (GTK_WIDGET_MAPPED (notebook)) + pm = gdk_pixmap_new (widget->window, w, h, 1); + pmgc = gdk_gc_new (pm); + + /* clear the shape mask */ + col.pixel = 0; + gdk_gc_set_foreground(pmgc, &col); + gdk_draw_rectangle(pm, pmgc, TRUE, 0, 0, w, h); + + col.pixel = 1; + gdk_gc_set_foreground(pmgc, &col); + + /* draw the shape for the notebook page itself */ + x = GTK_CONTAINER(notebook)->border_width; + y = GTK_CONTAINER(notebook)->border_width; + width = widget->allocation.width - x * 2; + height = widget->allocation.height - y * 2; + + if (notebook->show_tabs && notebook->children) { - if (GTK_WIDGET_REALIZED (notebook->cur_page->child)) - gtk_widget_map (notebook->cur_page->child); + if (!(notebook->show_tabs)) + { + page = notebook->first_tab->data; + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + y += page->allocation.height + + widget->style->klass->ythickness; + case GTK_POS_BOTTOM: + height -= page->allocation.height + + widget->style->klass->ythickness; + break; + case GTK_POS_LEFT: + x += page->allocation.width + + widget->style->klass->xthickness; + case GTK_POS_RIGHT: + width -= page->allocation.width + + widget->style->klass->xthickness; + break; + } + } else { - gtk_widget_map (notebook->cur_page->child); - gtk_widget_size_allocate (GTK_WIDGET (notebook), - >K_WIDGET (notebook)->allocation); + page = notebook->cur_page; + if (!GTK_WIDGET_MAPPED (page->tab_label)) + { + if (notebook->tab_pos == GTK_POS_LEFT) + { + x -= widget->style->klass->xthickness * 2; + width += widget->style->klass->xthickness * 2; + } + else if (notebook->tab_pos == GTK_POS_RIGHT) + width += widget->style->klass->xthickness * 2; + } + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + y += page->allocation.height; + case GTK_POS_BOTTOM: + height -= page->allocation.height; + break; + case GTK_POS_LEFT: + x += page->allocation.width; + case GTK_POS_RIGHT: + width -= page->allocation.width; + break; + } } } - - if (GTK_WIDGET_DRAWABLE (notebook)) - gtk_widget_queue_draw (GTK_WIDGET (notebook)); - gtk_notebook_set_shape (notebook); + gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); + + /* if theres an area for scrollign arrows draw the shape for them */ + if (notebook->panel) + { + gdk_window_get_geometry(notebook->panel, &x, &y, &width, &height, &depth); + gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); + } + + /* draw the shapes of all the children */ + children = notebook->children; + while (children) + { + page = children->data; + if (GTK_WIDGET_MAPPED (page->tab_label)) + { + x = page->allocation.x; + y = page->allocation.y; + width = page->allocation.width; + height = page->allocation.height; + gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); + } + children = children->next; + } + /* set the mask */ + gdk_window_shape_combine_mask(widget->window, pm, 0, 0); + gdk_pixmap_unref(pm); + gdk_gc_destroy(pmgc); } +/* Private GtkNotebook Size Allocate Functions: + * + * gtk_notebook_pages_allocate + * gtk_notebook_page_allocate + * gtk_notebook_calc_tabs + */ static void -gtk_notebook_draw_tab (GtkNotebook *notebook, - GtkNotebookPage *page, - GdkRectangle *area) +gtk_notebook_pages_allocate (GtkNotebook *notebook, + GtkAllocation *allocation) { - GdkRectangle child_area; - GdkRectangle page_area; - GtkStateType state_type; - GtkPositionType gap_side; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (page != NULL); - g_return_if_fail (area != NULL); + GtkWidget *widget; + GtkContainer *container; + GtkNotebookPage *page = NULL; + GtkAllocation child_allocation; + GList *children = NULL; + GList *last_child = NULL; + gboolean showarrow = FALSE; + gint tab_space = 0; + gint delta; + gint x = 0; + gint y = 0; + gint i; + gint n = 1; + gint old_fill = 0; + gint new_fill = 0; - if (!GTK_WIDGET_MAPPED (page->tab_label) || - (page->allocation.width == 0) || (page->allocation.height == 0)) + if (!notebook->show_tabs || !notebook->children || !notebook->cur_page) return; - page_area.x = page->allocation.x; - page_area.y = page->allocation.y; - page_area.width = page->allocation.width; - page_area.height = page->allocation.height; + widget = GTK_WIDGET (notebook); + container = GTK_CONTAINER (notebook); - if (gdk_rectangle_intersect (&page_area, area, &child_area)) + child_allocation.x = container->border_width; + child_allocation.y = container->border_width; + + switch (notebook->tab_pos) { - GtkWidget *widget; + case GTK_POS_BOTTOM: + child_allocation.y = (allocation->height - + notebook->cur_page->requisition.height - + container->border_width); + case GTK_POS_TOP: + child_allocation.height = notebook->cur_page->requisition.height; + break; + case GTK_POS_RIGHT: + child_allocation.x = (allocation->width - + notebook->cur_page->requisition.width - + container->border_width); + case GTK_POS_LEFT: + child_allocation.width = notebook->cur_page->requisition.width; + break; + } + + if (notebook->scrollable) + { + GList *focus_tab; + + children = notebook->children; + + if (notebook->focus_tab) + focus_tab = notebook->focus_tab; + else if (notebook->first_tab) + focus_tab = notebook->first_tab; + else + focus_tab = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE); - widget = GTK_WIDGET (notebook); - gap_side = 0; switch (notebook->tab_pos) { case GTK_POS_TOP: - gap_side = GTK_POS_BOTTOM; - break; case GTK_POS_BOTTOM: - gap_side = GTK_POS_TOP; + while (children) + { + page = children->data; + children = children->next; + + if (GTK_WIDGET_VISIBLE (page->child)) + tab_space += page->requisition.width; + } + if (tab_space > + allocation->width - 2 * container->border_width - TAB_OVERLAP) + { + showarrow = TRUE; + page = focus_tab->data; + + tab_space = (allocation->width - TAB_OVERLAP - + page->requisition.width - + 2 * (container->border_width + ARROW_SPACING + + ARROW_SIZE)); + x = (allocation->width - 2 * ARROW_SIZE - ARROW_SPACING - + container->border_width); + + page = notebook->children->data; + if (notebook->tab_pos == GTK_POS_TOP) + y = (container->border_width + + (page->requisition.height - ARROW_SIZE) / 2); + else + y = (allocation->height - container->border_width - + ARROW_SIZE - (page->requisition.height - ARROW_SIZE) / 2); + } break; case GTK_POS_LEFT: - gap_side = GTK_POS_RIGHT; - break; case GTK_POS_RIGHT: - gap_side = GTK_POS_LEFT; + while (children) + { + page = children->data; + children = children->next; + + if (GTK_WIDGET_VISIBLE (page->child)) + tab_space += page->requisition.height; + } + if (tab_space > + (allocation->height - 2 * container->border_width - TAB_OVERLAP)) + { + showarrow = TRUE; + page = focus_tab->data; + tab_space = (allocation->height - + ARROW_SIZE - ARROW_SPACING - TAB_OVERLAP - + 2 * container->border_width - + page->requisition.height); + y = allocation->height - container->border_width - ARROW_SIZE; + + page = notebook->children->data; + if (notebook->tab_pos == GTK_POS_LEFT) + x = (container->border_width + + (page->requisition.width - + (2 * ARROW_SIZE - ARROW_SPACING)) / 2); + else + x = (allocation->width - container->border_width - + (2 * ARROW_SIZE - ARROW_SPACING) - + (page->requisition.width - + (2 * ARROW_SIZE - ARROW_SPACING)) / 2); + } break; } - - if (notebook->cur_page == page) - state_type = GTK_STATE_NORMAL; - else - state_type = GTK_STATE_ACTIVE; - gtk_paint_extension(widget->style, widget->window, - state_type, GTK_SHADOW_OUT, - area, widget, "tab", - page_area.x, page_area.y, - page_area.width, page_area.height, - gap_side); - if ((GTK_WIDGET_HAS_FOCUS (widget)) && - notebook->focus_tab && (notebook->focus_tab->data == page) && - (page)) + if (showarrow) /* first_tab <- focus_tab */ + { + if (tab_space <= 0) + { + notebook->first_tab = focus_tab; + last_child = gtk_notebook_search_page (notebook, focus_tab, + STEP_NEXT, TRUE); + } + else + { + children = NULL; + if (notebook->first_tab && notebook->first_tab != focus_tab) + { + /* Is first_tab really predecessor of focus_tab ? */ + page = notebook->first_tab->data; + if (GTK_WIDGET_VISIBLE (page->child)) + for (children = focus_tab; + children && children != notebook->first_tab; + children = gtk_notebook_search_page (notebook, + children, + STEP_PREV, + TRUE)); + } + if (!children) + notebook->first_tab = focus_tab; + else + gtk_notebook_calc_tabs (notebook, + gtk_notebook_search_page (notebook, + focus_tab, + STEP_PREV, + TRUE), + &(notebook->first_tab), &tab_space, + STEP_PREV); + + if (tab_space <= 0) + { + notebook->first_tab = + gtk_notebook_search_page (notebook, notebook->first_tab, + STEP_NEXT, TRUE); + if (!notebook->first_tab) + notebook->first_tab = focus_tab; + last_child = gtk_notebook_search_page (notebook, focus_tab, + STEP_NEXT, TRUE); + } + else /* focus_tab -> end */ + { + if (!notebook->first_tab) + notebook->first_tab = gtk_notebook_search_page (notebook, + NULL, + STEP_NEXT, + TRUE); + children = NULL; + gtk_notebook_calc_tabs (notebook, + gtk_notebook_search_page (notebook, + focus_tab, + STEP_NEXT, + TRUE), + &children, &tab_space, STEP_NEXT); + + if (tab_space <= 0) + last_child = children; + else /* start <- first_tab */ + { + last_child = NULL; + children = NULL; + gtk_notebook_calc_tabs + (notebook, + gtk_notebook_search_page (notebook, + notebook->first_tab, + STEP_PREV, + TRUE), + &children, &tab_space, STEP_PREV); + notebook->first_tab = gtk_notebook_search_page(notebook, + children, + STEP_NEXT, + TRUE); + } + } + } + + if (GTK_WIDGET_REALIZED (notebook)) + { + gdk_window_move (notebook->panel, x, y); + gdk_window_show (notebook->panel); + } + + if (tab_space < 0) + { + tab_space = -tab_space; + n = 0; + for (children = notebook->first_tab; + children && children != last_child; + children = gtk_notebook_search_page (notebook, children, + STEP_NEXT, TRUE)) + n++; + } + else + tab_space = 0; + + /*unmap all non-visible tabs*/ + for (children = gtk_notebook_search_page (notebook, NULL, + STEP_NEXT, TRUE); + children && children != notebook->first_tab; + children = gtk_notebook_search_page (notebook, children, + STEP_NEXT, TRUE)) + { + page = children->data; + if (page->tab_label && GTK_WIDGET_MAPPED (page->tab_label)) + gtk_widget_unmap (page->tab_label); + } + for (children = last_child; children; + children = gtk_notebook_search_page (notebook, children, + STEP_NEXT, TRUE)) + { + page = children->data; + if (page->tab_label && GTK_WIDGET_MAPPED (page->tab_label)) + gtk_widget_unmap (page->tab_label); + } + } + else /* !showarrow */ { - gtk_paint_focus (widget->style, widget->window, - area, widget, "tab", - page->tab_label->allocation.x - 1, - page->tab_label->allocation.y - 1, - page->tab_label->allocation.width + 1, - page->tab_label->allocation.height + 1); + notebook->first_tab = gtk_notebook_search_page (notebook, NULL, + STEP_NEXT, TRUE); + tab_space = 0; + if (GTK_WIDGET_REALIZED (notebook)) + gdk_window_hide (notebook->panel); } - if (gtk_widget_intersect (page->tab_label, area, &child_area)) - gtk_widget_draw (page->tab_label, &child_area); } -} -static void -gtk_notebook_set_focus_child (GtkContainer *container, - GtkWidget *child) -{ - GtkNotebook *notebook; - - g_return_if_fail (container != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (container)); - - if (child) + if (!showarrow) { - g_return_if_fail (GTK_IS_WIDGET (child)); - - notebook = GTK_NOTEBOOK (container); + gint c = 0; - notebook->child_has_focus = TRUE; - if (!notebook->focus_tab) + n = 0; + children = notebook->children; + switch (notebook->tab_pos) { - GList *children; - GtkNotebookPage *page; + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + while (children) + { + page = children->data; + children = children->next; - children = notebook->children; + if (GTK_WIDGET_VISIBLE (page->child)) + { + c++; + tab_space += page->requisition.width; + if (page->expand) + n++; + } + } + tab_space -= allocation->width; + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: while (children) { page = children->data; - if (page->child == child || page->tab_label == child) - gtk_notebook_switch_focus_tab (notebook, children); children = children->next; + + if (GTK_WIDGET_VISIBLE (page->child)) + { + c++; + tab_space += page->requisition.height; + if (page->expand) + n++; + } } + tab_space -= allocation->height; } + tab_space += 2 * container->border_width + TAB_OVERLAP; + tab_space *= -1; + notebook->first_tab = gtk_notebook_search_page (notebook, NULL, + STEP_NEXT, TRUE); + if (notebook->homogeneous && n) + n = c; } - parent_class->set_focus_child (container, child); -} + + children = notebook->first_tab; + i = 1; + while (children) + { + if (children == last_child) + { + gtk_notebook_set_shape (notebook); + return; + children = NULL; + break; + } -static gint -gtk_notebook_focus_in (GtkWidget *widget, - GdkEventFocus *event) -{ - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); + page = children->data; + if (!showarrow && page->pack != GTK_PACK_START) + break; + children = gtk_notebook_search_page (notebook, children, STEP_NEXT,TRUE); + + delta = 0; + if (n && (showarrow || page->expand || notebook->homogeneous)) + { + new_fill = (tab_space * i++) / n; + delta = new_fill - old_fill; + old_fill = new_fill; + } + + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + child_allocation.width = (page->requisition.width + + TAB_OVERLAP + delta); + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + child_allocation.height = (page->requisition.height + + TAB_OVERLAP + delta); + break; + } - GTK_NOTEBOOK (widget)->child_has_focus = FALSE; - GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); - gtk_widget_draw_focus (widget); + gtk_notebook_page_allocate (notebook, page, &child_allocation); + + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + child_allocation.x += child_allocation.width - TAB_OVERLAP; + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + child_allocation.y += child_allocation.height - TAB_OVERLAP; + break; + } - return FALSE; -} + if (GTK_WIDGET_REALIZED (notebook) && + page->tab_label && !GTK_WIDGET_MAPPED (page->tab_label)) + gtk_widget_map (page->tab_label); + } -static gint -gtk_notebook_focus_out (GtkWidget *widget, - GdkEventFocus *event) -{ - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); + if (children) + { + children = notebook->children; + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + child_allocation.x = (allocation->x + allocation->width - + container->border_width); + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + child_allocation.y = (allocation->y + allocation->height - + container->border_width); + break; + } - GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); - gtk_widget_draw_focus (widget); + while (children != last_child) + { + page = children->data; + children = children->next; - return FALSE; -} + if (page->pack != GTK_PACK_END || !GTK_WIDGET_VISIBLE (page->child)) + continue; -static void -gtk_notebook_draw_focus (GtkWidget *widget) -{ - GtkNotebook *notebook; + delta = 0; + if (n && (page->expand || notebook->homogeneous)) + { + new_fill = (tab_space * i++) / n; + delta = new_fill - old_fill; + old_fill = new_fill; + } - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + child_allocation.width = (page->requisition.width + + TAB_OVERLAP + delta); + child_allocation.x -= child_allocation.width; + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + child_allocation.height = (page->requisition.height + + TAB_OVERLAP + delta); + child_allocation.y -= child_allocation.height; + break; + } - notebook = GTK_NOTEBOOK (widget); + gtk_notebook_page_allocate (notebook, page, &child_allocation); - if (GTK_WIDGET_DRAWABLE (widget) && notebook->show_tabs && - notebook->focus_tab) - { - GtkNotebookPage *page; - GdkRectangle area; - - page = notebook->focus_tab->data; - - area.x = widget->allocation.x; - area.y = widget->allocation.y; - area.width = widget->allocation.width; - area.height = widget->allocation.height; - - gtk_notebook_draw_tab(GTK_NOTEBOOK(widget), page, &area); + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + child_allocation.x += TAB_OVERLAP; + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + child_allocation.y += TAB_OVERLAP; + break; + } + + if (GTK_WIDGET_REALIZED (notebook) && page->tab_label && + !GTK_WIDGET_MAPPED (page->tab_label)) + gtk_widget_map (page->tab_label); + } } + gtk_notebook_set_shape (notebook); } static void -gtk_notebook_focus_changed (GtkNotebook *notebook, GtkNotebookPage *old_page) +gtk_notebook_page_allocate (GtkNotebook *notebook, + GtkNotebookPage *page, + GtkAllocation *allocation) { + GtkAllocation child_allocation; + gint xthickness; + gint ythickness; + gint padding; + g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (page != NULL); + g_return_if_fail (allocation != NULL); - gtk_notebook_expose_tabs(notebook); -} + page->allocation = *allocation; -static void -gtk_notebook_calc_tabs (GtkNotebook *notebook, - GList *start, - GList **end, - gint *tab_space, - guint direction) -{ - GtkNotebookPage *page = NULL; - GList *children; + xthickness = GTK_WIDGET (notebook)->style->klass->xthickness; + ythickness = GTK_WIDGET (notebook)->style->klass->ythickness; + + if (notebook->cur_page != page) + { + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + page->allocation.y += ythickness; + case GTK_POS_BOTTOM: + page->allocation.height -= ythickness; + break; + case GTK_POS_LEFT: + page->allocation.x += xthickness; + case GTK_POS_RIGHT: + page->allocation.width -= xthickness; + break; + } + } - children = start; switch (notebook->tab_pos) { case GTK_POS_TOP: case GTK_POS_BOTTOM: - while (children) + padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_hborder; + if (page->fill) { - page = children->data; - *tab_space -= page->requisition.width; - if (*tab_space < 0 || children == *end) - { - if (*tab_space < 0) - { - *tab_space = - (*tab_space + page->requisition.width); - *end = children; - } - break; - } - if (direction == STEP_NEXT) - children = children->next; - else - children = children->prev; + child_allocation.x = (xthickness + FOCUS_WIDTH + + notebook->tab_hborder); + child_allocation.width = (page->allocation.width - + 2 * child_allocation.x); + child_allocation.x += page->allocation.x; + } + else + { + child_allocation.x = (page->allocation.x + + (page->allocation.width - + page->tab_label->requisition.width) / 2); + child_allocation.width = page->tab_label->requisition.width; } + child_allocation.y = (notebook->tab_vborder + FOCUS_WIDTH + + page->allocation.y); + if (notebook->tab_pos == GTK_POS_TOP) + child_allocation.y += ythickness; + child_allocation.height = (page->allocation.height - ythickness - + 2 * (notebook->tab_vborder + FOCUS_WIDTH)); break; case GTK_POS_LEFT: case GTK_POS_RIGHT: - while (children) + padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_vborder; + if (page->fill) { - page = children->data; - *tab_space -= page->requisition.height; - if (*tab_space < 0 || children == *end) - { - if (*tab_space < 0) - { - *tab_space = - (*tab_space + page->requisition.height); - *end = children; - } - break; - } - if (direction == STEP_NEXT) - children = children->next; - else - children = children->prev; + child_allocation.y = ythickness + padding; + child_allocation.height = (page->allocation.height - + 2 * child_allocation.y); + child_allocation.y += page->allocation.y; + } + else + { + child_allocation.y = (page->allocation.y + + (page->allocation.height - + page->tab_label->requisition.height) / 2); + child_allocation.height = page->tab_label->requisition.height; } + child_allocation.x = (page->allocation.x + notebook->tab_hborder + + FOCUS_WIDTH); + if (notebook->tab_pos == GTK_POS_LEFT) + child_allocation.x += xthickness; + child_allocation.width = (page->allocation.width - xthickness - + 2 * (notebook->tab_hborder + FOCUS_WIDTH)); break; } + + if (page->tab_label) + gtk_widget_size_allocate (page->tab_label, &child_allocation); } -static void -gtk_notebook_pages_allocate (GtkNotebook *notebook, - GtkAllocation *allocation) +static void +gtk_notebook_calc_tabs (GtkNotebook *notebook, + GList *start, + GList **end, + gint *tab_space, + guint direction) { - GtkWidget *widget; - GtkContainer *container; GtkNotebookPage *page = NULL; - GtkAllocation child_allocation; GList *children; - GList *last_child = NULL; - gint showarrow = FALSE; - gint tab_space = 0; - gint x = 0; - gint y = 0; - gint i; - gint n = 1; - gint old_fill = 0; - gint new_fill = 0; - - if (!notebook->show_tabs || !notebook->children) + GList *last_list = NULL; + gboolean pack; + + if (!start) return; - - widget = GTK_WIDGET (notebook); - container = GTK_CONTAINER (notebook); - - child_allocation.x = container->border_width; - child_allocation.y = container->border_width; - - switch (notebook->tab_pos) - { - case GTK_POS_BOTTOM: - child_allocation.y = (allocation->height - - notebook->cur_page->requisition.height - - container->border_width); - case GTK_POS_TOP: - child_allocation.height = notebook->cur_page->requisition.height; - break; - case GTK_POS_RIGHT: - child_allocation.x = (allocation->width - - notebook->cur_page->requisition.width - - container->border_width); - case GTK_POS_LEFT: - child_allocation.width = notebook->cur_page->requisition.width; - break; - } - - if (notebook->scrollable) - { - GList *focus_tab; - - children = notebook->children; - - if (notebook->focus_tab) - focus_tab = notebook->focus_tab; - else if (notebook->first_tab) - focus_tab = notebook->first_tab; - else - focus_tab = notebook->children; + children = start; + pack = GTK_NOTEBOOK_PAGE (start)->pack; + if (pack == GTK_PACK_END) + direction = (direction == STEP_PREV) ? STEP_NEXT : STEP_PREV; + + while (1) + { switch (notebook->tab_pos) { case GTK_POS_TOP: @@ -2548,24 +3005,28 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook, while (children) { page = children->data; - children = children->next; - tab_space += page->requisition.width; - } - if (tab_space > allocation->width - 2 * container->border_width - TAB_OVERLAP) - { - showarrow = TRUE; - page = focus_tab->data; - - tab_space = (allocation->width - TAB_OVERLAP - page->requisition.width - - 2 * (container->border_width + ARROW_SPACING + ARROW_SIZE)); - x = allocation->width - 2 * ARROW_SIZE - ARROW_SPACING - container->border_width; - - page = notebook->children->data; - if (notebook->tab_pos == GTK_POS_TOP) - y = container->border_width + (page->requisition.height - ARROW_SIZE) / 2; + if (GTK_WIDGET_VISIBLE (page->child)) + { + if (page->pack == pack) + { + *tab_space -= page->requisition.width; + if (*tab_space < 0 || children == *end) + { + if (*tab_space < 0) + { + *tab_space = - (*tab_space + + page->requisition.width); + *end = children; + } + return; + } + } + last_list = children; + } + if (direction == STEP_NEXT) + children = children->next; else - y = (allocation->height - container->border_width - - ARROW_SIZE - (page->requisition.height - ARROW_SIZE) / 2); + children = children->prev; } break; case GTK_POS_LEFT: @@ -2573,847 +3034,1126 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook, while (children) { page = children->data; - children = children->next; - tab_space += page->requisition.height; - } - if (tab_space > (allocation->height - 2 * container->border_width - TAB_OVERLAP)) - { - showarrow = TRUE; - page = focus_tab->data; - tab_space = (allocation->height - - ARROW_SIZE - ARROW_SPACING - TAB_OVERLAP - - 2 * container->border_width - page->requisition.height); - y = allocation->height - container->border_width - ARROW_SIZE; - - page = notebook->children->data; - if (notebook->tab_pos == GTK_POS_LEFT) - x = (container->border_width + - (page->requisition.width - (2 * ARROW_SIZE - ARROW_SPACING)) / 2); + if (GTK_WIDGET_VISIBLE (page->child)) + { + if (page->pack == pack) + { + *tab_space -= page->requisition.height; + if (*tab_space < 0 || children == *end) + { + if (*tab_space < 0) + { + *tab_space = - (*tab_space + + page->requisition.height); + *end = children; + } + return; + } + } + last_list = children; + } + if (direction == STEP_NEXT) + children = children->next; else - x = (allocation->width - container->border_width - - (2 * ARROW_SIZE - ARROW_SPACING) - - (page->requisition.width - (2 * ARROW_SIZE - ARROW_SPACING)) / 2); + children = children->prev; } break; } - if (showarrow) /* first_tab <- focus_tab */ - { - children = focus_tab->prev; - while (children) - { - if (notebook->first_tab == children) - break; - children = children->prev; - } - - if (!children) - notebook->first_tab = focus_tab; - else - gtk_notebook_calc_tabs (notebook, focus_tab->prev, - &(notebook->first_tab), &tab_space, - STEP_PREV); - if (tab_space <= 0) - { - notebook->first_tab = notebook->first_tab->next; - if (!notebook->first_tab) - notebook->first_tab = focus_tab; - last_child = focus_tab->next; - } - else /* focus_tab -> end */ - { - if (!notebook->first_tab) - notebook->first_tab = notebook->children; - - children = NULL; - gtk_notebook_calc_tabs (notebook, focus_tab->next, - &children, &tab_space, STEP_NEXT); - - if (tab_space <= 0) - last_child = children; - else /* start <- first_tab */ - { - last_child = NULL; - children = NULL; - gtk_notebook_calc_tabs (notebook,notebook->first_tab->prev, - &children, &tab_space, STEP_PREV); - if (children) - notebook->first_tab = children->next; - else - notebook->first_tab = notebook->children; - } - } - - if (GTK_WIDGET_REALIZED (notebook)) - { - gdk_window_move (notebook->panel, x, y); - gdk_window_show (notebook->panel); - } - - if (tab_space < 0) - { - tab_space = -tab_space; - n = 0; - children = notebook->first_tab; - while (children != last_child) - { - children = children->next; - n++; - } - } - else - tab_space = 0; - - children = notebook->children; - while (children != notebook->first_tab) + if (direction == STEP_PREV) + return; + pack = (pack == GTK_PACK_END) ? GTK_PACK_START : GTK_PACK_END; + direction = STEP_PREV; + children = last_list; + } +} + +/* Private GtkNotebook Page Switch Methods: + * + * gtk_notebook_real_switch_page + */ +static void +gtk_notebook_real_switch_page (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (page != NULL); + + if (notebook->cur_page == page || !GTK_WIDGET_VISIBLE (page->child)) + return; + + if (notebook->cur_page && GTK_WIDGET_MAPPED (notebook->cur_page->child)) + gtk_widget_unmap (notebook->cur_page->child); + + notebook->cur_page = page; + + if (!notebook->focus_tab || + notebook->focus_tab->data != (gpointer) notebook->cur_page) + notebook->focus_tab = + g_list_find (notebook->children, notebook->cur_page); + + gtk_notebook_pages_allocate (notebook, >K_WIDGET (notebook)->allocation); + gtk_notebook_expose_tabs (notebook); + + if (GTK_WIDGET_MAPPED (notebook)) + { + if (GTK_WIDGET_REALIZED (notebook->cur_page->child)) + gtk_widget_map (notebook->cur_page->child); + else + { + gtk_widget_map (notebook->cur_page->child); + gtk_widget_size_allocate (GTK_WIDGET (notebook), + >K_WIDGET (notebook)->allocation); + } + } + + if (GTK_WIDGET_DRAWABLE (notebook)) + gtk_widget_queue_draw (GTK_WIDGET (notebook)); + gtk_notebook_set_shape (notebook); +} + +/* Private GtkNotebook Page Switch Functions: + * + * gtk_notebook_switch_page + * gtk_notebook_page_select + * gtk_notebook_switch_focus_tab + * gtk_notebook_menu_switch_page + */ +static void +gtk_notebook_switch_page (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (page != NULL); + + if (notebook->cur_page == page) + return; + + if (page_num < 0) + page_num = g_list_index (notebook->children, page); + + gtk_signal_emit (GTK_OBJECT (notebook), + notebook_signals[SWITCH_PAGE], + page, + page_num); +} + +static gint +gtk_notebook_page_select (GtkNotebook *notebook) +{ + GtkNotebookPage *page; + + g_return_val_if_fail (notebook != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE); + + if (!notebook->focus_tab) + return FALSE; + + page = notebook->focus_tab->data; + gtk_notebook_switch_page (notebook, page, -1); + + if (GTK_WIDGET_VISIBLE (page->child)) + { + if (GTK_IS_CONTAINER (page->child)) + { + if (gtk_container_focus (GTK_CONTAINER (page->child), + GTK_DIR_TAB_FORWARD)) + return TRUE; + } + else if (GTK_WIDGET_CAN_FOCUS (page->child)) + { + gtk_widget_grab_focus (page->child); + return TRUE; + } + } + return FALSE; +} + +static void +gtk_notebook_switch_focus_tab (GtkNotebook *notebook, + GList *new_child) +{ + GList *old_child; + GtkNotebookPage *old_page = NULL; + GtkNotebookPage *page; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (notebook->focus_tab == new_child) + return; + + old_child = notebook->focus_tab; + notebook->focus_tab = new_child; + + if (notebook->scrollable && GTK_WIDGET_DRAWABLE (notebook)) + { + if ((new_child == NULL) != (old_child == NULL)) + { + gdk_window_clear (notebook->panel); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + } + else + { + GList *olist; + GList *nlist; + + olist = gtk_notebook_search_page (notebook, old_child, + STEP_PREV, TRUE); + nlist = gtk_notebook_search_page (notebook, new_child, + STEP_PREV, TRUE); + + if ((olist == NULL) != (nlist == NULL)) { - page = children->data; - children = children->next; - - if (page->tab_label && GTK_WIDGET_MAPPED (page->tab_label)) - gtk_widget_unmap (page->tab_label); - + gdk_window_clear_area (notebook->panel, 0, 0, + ARROW_SIZE, ARROW_SIZE); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); } - children = last_child; - while (children) + + olist = gtk_notebook_search_page (notebook, old_child, + STEP_NEXT, TRUE); + nlist = gtk_notebook_search_page (notebook, new_child, + STEP_NEXT, TRUE); + + if ((olist == NULL) != (nlist == NULL)) { - page = children->data; - children = children->next; - - if (page->tab_label && GTK_WIDGET_MAPPED (page->tab_label)) - gtk_widget_unmap (page->tab_label); + gdk_window_clear_area (notebook->panel, + ARROW_SIZE + ARROW_SPACING, 0, + ARROW_SIZE, ARROW_SIZE); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); } } - else /* !showarrow */ - { - notebook->first_tab = notebook->children; - tab_space = 0; - if (GTK_WIDGET_REALIZED (notebook)) - gdk_window_hide (notebook->panel); - } - children = notebook->first_tab; } - else - children = notebook->children; - - i = 1; - while (children != last_child) + + if (!notebook->show_tabs || !notebook->focus_tab) + return; + + if (old_child) + old_page = old_child->data; + + page = notebook->focus_tab->data; + if (GTK_WIDGET_MAPPED (page->tab_label)) + gtk_notebook_focus_changed (notebook, old_page); + else + { + gtk_notebook_pages_allocate (notebook, + &(GTK_WIDGET (notebook)->allocation)); + gtk_notebook_expose_tabs (notebook); + } + + gtk_notebook_set_shape (notebook); +} + +static void +gtk_notebook_menu_switch_page (GtkWidget *widget, + GtkNotebookPage *page) +{ + GtkNotebook *notebook; + GList *children; + guint page_num; + + g_return_if_fail (widget != NULL); + g_return_if_fail (page != NULL); + + notebook = GTK_NOTEBOOK (gtk_menu_get_attach_widget + (GTK_MENU (widget->parent))); + + if (notebook->cur_page == page) + return; + + page_num = 0; + children = notebook->children; + while (children && children->data != page) + { + children = children->next; + page_num++; + } + + gtk_signal_emit (GTK_OBJECT (notebook), + notebook_signals[SWITCH_PAGE], + page, + page_num); +} + +/* Private GtkNotebook Menu Functions: + * + * gtk_notebook_menu_item_create + * gtk_notebook_menu_label_unparent + * gtk_notebook_menu_detacher + */ +static void +gtk_notebook_menu_item_create (GtkNotebook *notebook, + GList *list) +{ + GtkNotebookPage *page; + GtkWidget *menu_item; + + page = list->data; + if (page->default_menu) + { + if (page->tab_label && GTK_IS_LABEL (page->tab_label)) + page->menu_label = gtk_label_new (GTK_LABEL (page->tab_label)->label); + else + page->menu_label = gtk_label_new (""); + gtk_misc_set_alignment (GTK_MISC (page->menu_label), 0.0, 0.5); + } + + gtk_widget_show (page->menu_label); + menu_item = gtk_menu_item_new (); + gtk_widget_freeze_accelerators (menu_item); + gtk_container_add (GTK_CONTAINER (menu_item), page->menu_label); + gtk_menu_insert (GTK_MENU (notebook->menu), menu_item, + gtk_notebook_real_page_position (notebook, list)); + gtk_signal_connect (GTK_OBJECT (menu_item), "activate", + GTK_SIGNAL_FUNC (gtk_notebook_menu_switch_page), page); + if (GTK_WIDGET_VISIBLE (page->child)) + gtk_widget_show (menu_item); +} + +static void +gtk_notebook_menu_label_unparent (GtkWidget *widget, + gpointer data) +{ + gtk_widget_unparent (GTK_BIN(widget)->child); + GTK_BIN(widget)->child = NULL; +} + +static void +gtk_notebook_menu_detacher (GtkWidget *widget, + GtkMenu *menu) +{ + GtkNotebook *notebook; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + + notebook = GTK_NOTEBOOK (widget); + g_return_if_fail (notebook->menu == (GtkWidget*) menu); + + notebook->menu = NULL; +} + +/* Public GtkNotebook Page Insert/Remove Methods : + * + * gtk_notebook_append_page + * gtk_notebook_append_page_menu + * gtk_notebook_prepend_page + * gtk_notebook_prepend_page_menu + * gtk_notebook_insert_page + * gtk_notebook_insert_page_menu + * gtk_notebook_remove_page + */ +void +gtk_notebook_append_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label) +{ + gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, -1); +} + +void +gtk_notebook_append_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label) +{ + gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, -1); +} + +void +gtk_notebook_prepend_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label) +{ + gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, 0); +} + +void +gtk_notebook_prepend_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label) +{ + gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, 0); +} + +void +gtk_notebook_insert_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + gint position) +{ + gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position); +} + +void +gtk_notebook_insert_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label, + gint position) +{ + GtkNotebookPage *page; + gint nchildren; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); + + page = g_new (GtkNotebookPage, 1); + page->child = child; + page->requisition.width = 0; + page->requisition.height = 0; + page->allocation.x = 0; + page->allocation.y = 0; + page->allocation.width = 0; + page->allocation.height = 0; + page->default_menu = FALSE; + page->default_tab = FALSE; + + nchildren = g_list_length (notebook->children); + if ((position < 0) || (position > nchildren)) + position = nchildren; + + notebook->children = g_list_insert (notebook->children, page, position); + + if (!tab_label) + { + page->default_tab = TRUE; + if (notebook->show_tabs) + tab_label = gtk_label_new (""); + } + page->tab_label = tab_label; + page->menu_label = menu_label; + page->expand = FALSE; + page->fill = TRUE; + page->pack = GTK_PACK_START; + + if (!menu_label) + page->default_menu = TRUE; + else { - page = children->data; - children = children->next; - - if (GTK_WIDGET_VISIBLE (page->child)) + gtk_widget_ref (page->menu_label); + gtk_object_sink (GTK_OBJECT(page->menu_label)); + } + + if (notebook->menu) + gtk_notebook_menu_item_create (notebook, + g_list_find (notebook->children, page)); + + gtk_notebook_update_labels (notebook); + + if (!notebook->first_tab) + notebook->first_tab = notebook->children; + + gtk_widget_set_parent (child, GTK_WIDGET (notebook)); + if (tab_label) + gtk_widget_set_parent (tab_label, GTK_WIDGET (notebook)); + + if (!notebook->cur_page) + { + gtk_notebook_switch_page (notebook, page, 0); + gtk_notebook_switch_focus_tab (notebook, NULL); + } + + if (GTK_WIDGET_VISIBLE (notebook)) + { + if (GTK_WIDGET_REALIZED (notebook) && + !GTK_WIDGET_REALIZED (child)) + gtk_widget_realize (child); + + if (GTK_WIDGET_MAPPED (notebook) && + !GTK_WIDGET_MAPPED (child) && notebook->cur_page == page) + gtk_widget_map (child); + + if (tab_label) { - new_fill = (tab_space * i++) / n; - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - case GTK_POS_BOTTOM: - child_allocation.width = page->requisition.width + TAB_OVERLAP + new_fill - old_fill; - break; - case GTK_POS_LEFT: - case GTK_POS_RIGHT: - child_allocation.height = page->requisition.height + TAB_OVERLAP + new_fill - old_fill; - break; - } - old_fill = new_fill; - gtk_notebook_page_allocate (notebook, page, &child_allocation); - - switch (notebook->tab_pos) + if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child)) { - case GTK_POS_TOP: - case GTK_POS_BOTTOM: - child_allocation.x += child_allocation.width - TAB_OVERLAP; - break; - case GTK_POS_LEFT: - case GTK_POS_RIGHT: - child_allocation.y += child_allocation.height - TAB_OVERLAP; - break; + if (!GTK_WIDGET_VISIBLE (tab_label)) + gtk_widget_show (tab_label); + + if (GTK_WIDGET_REALIZED (notebook) && + !GTK_WIDGET_REALIZED (tab_label)) + gtk_widget_realize (tab_label); + + if (GTK_WIDGET_MAPPED (notebook) && + !GTK_WIDGET_MAPPED (tab_label)) + gtk_widget_map (tab_label); } - - if (GTK_WIDGET_REALIZED (notebook) && - page->tab_label && !GTK_WIDGET_MAPPED (page->tab_label)) - gtk_widget_map (page->tab_label); + else if (GTK_WIDGET_VISIBLE (tab_label)) + gtk_widget_hide (tab_label); } } - gtk_notebook_set_shape (notebook); + + if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (notebook)) + gtk_widget_queue_resize (child); } -static void -gtk_notebook_page_allocate (GtkNotebook *notebook, - GtkNotebookPage *page, - GtkAllocation *allocation) +void +gtk_notebook_remove_page (GtkNotebook *notebook, + gint page_num) { - GtkAllocation child_allocation; - gint xthickness, ythickness; + GList *list; g_return_if_fail (notebook != NULL); - g_return_if_fail (page != NULL); - g_return_if_fail (allocation != NULL); - - page->allocation = *allocation; - - xthickness = GTK_WIDGET (notebook)->style->klass->xthickness; - ythickness = GTK_WIDGET (notebook)->style->klass->ythickness; + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - if (notebook->cur_page != page) + if (page_num >= 0) { - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - page->allocation.y += ythickness; - case GTK_POS_BOTTOM: - page->allocation.height -= ythickness; - break; - case GTK_POS_LEFT: - page->allocation.x += xthickness; - case GTK_POS_RIGHT: - page->allocation.width -= xthickness; - break; - } + list = g_list_nth (notebook->children, page_num); + if (list) + gtk_notebook_real_remove (notebook, list); } - - switch (notebook->tab_pos) + else { - case GTK_POS_TOP: - child_allocation.x = xthickness + notebook->tab_border; - child_allocation.y = ythickness + notebook->tab_border + page->allocation.y; - child_allocation.width = page->allocation.width - child_allocation.x * 2; - child_allocation.height = page->allocation.height - ythickness - 2 * notebook->tab_border; - child_allocation.x += page->allocation.x; - break; - case GTK_POS_BOTTOM: - child_allocation.x = xthickness + notebook->tab_border; - child_allocation.width = page->allocation.width - child_allocation.x * 2; - child_allocation.height = page->allocation.height - ythickness - 2 * notebook->tab_border; - child_allocation.x += page->allocation.x; - child_allocation.y = page->allocation.y + notebook->tab_border; - break; - case GTK_POS_LEFT: - child_allocation.x = xthickness + notebook->tab_border + page->allocation.x; - child_allocation.y = ythickness + notebook->tab_border; - child_allocation.width = page->allocation.width - xthickness - 2 * notebook->tab_border; - child_allocation.height = page->allocation.height - child_allocation.y * 2; - child_allocation.y += page->allocation.y; - break; - case GTK_POS_RIGHT: - child_allocation.y = ythickness + notebook->tab_border; - child_allocation.width = page->allocation.width - xthickness - 2 * notebook->tab_border; - child_allocation.height = page->allocation.height - child_allocation.y * 2; - child_allocation.x = page->allocation.x + notebook->tab_border; - child_allocation.y += page->allocation.y; - break; + list = g_list_last (notebook->children); + if (list) + gtk_notebook_real_remove (notebook, list); } - - if (page->tab_label) - gtk_widget_size_allocate (page->tab_label, &child_allocation); } -static void -gtk_notebook_menu_switch_page (GtkWidget *widget, - GtkNotebookPage *page) +/* Public GtkNotebook Page Switch Methods : + * gtk_notebook_current_page + * gtk_notebook_page_num + * gtk_notebook_set_page + * gtk_notebook_next_page + * gtk_notebook_prev_page + */ +gint +gtk_notebook_current_page (GtkNotebook *notebook) { - GtkNotebook *notebook; - GList *children; - guint page_num; + g_return_val_if_fail (notebook != NULL, -1); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); - g_return_if_fail (widget != NULL); - g_return_if_fail (page != NULL); + if (!notebook->cur_page) + return -1; - notebook = GTK_NOTEBOOK (gtk_menu_get_attach_widget - (GTK_MENU (widget->parent))); + return g_list_index (notebook->children, notebook->cur_page); +} - if (notebook->cur_page == page) - return; +gint +gtk_notebook_page_num (GtkNotebook *notebook, + GtkWidget *child) +{ + GList *children; + gint num; - page_num = 0; + g_return_val_if_fail (notebook != NULL, -1); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); + + num = 0; children = notebook->children; - while (children && children->data != page) + while (children) { + GtkNotebookPage *page; + + page = children->data; + if (page->child == child) + return num; + children = children->next; - page_num++; + num++; } - gtk_signal_emit (GTK_OBJECT (notebook), - notebook_signals[SWITCH_PAGE], - page, - page_num); + return -1; } -static void -gtk_notebook_switch_page (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num) -{ +void +gtk_notebook_set_page (GtkNotebook *notebook, + gint page_num) +{ + GList *list; + g_return_if_fail (notebook != NULL); g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (page != NULL); - - if (notebook->cur_page == page) + + if (page_num >= 0) + list = g_list_nth (notebook->children, page_num); + else + { + list = g_list_last (notebook->children); + page_num = g_list_length (notebook->children) - 1; + } + if (list) + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), page_num); +} + +void +gtk_notebook_next_page (GtkNotebook *notebook) +{ + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + list = g_list_find (notebook->children, notebook->cur_page); + if (!list) return; - gtk_signal_emit (GTK_OBJECT (notebook), - notebook_signals[SWITCH_PAGE], - page, - page_num); + list = gtk_notebook_search_page (notebook, list, STEP_NEXT, TRUE); + if (!list) + return; + + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1); } -static gint -gtk_notebook_focus (GtkContainer *container, - GtkDirectionType direction) +void +gtk_notebook_prev_page (GtkNotebook *notebook) { - GtkNotebook *notebook; - GtkWidget *focus_child; - GtkNotebookPage *page = NULL; - GtkNotebookPage *old_page = NULL; - gint return_val; + GList *list; - g_return_val_if_fail (container != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (container), FALSE); + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - notebook = GTK_NOTEBOOK (container); + list = g_list_find (notebook->children, notebook->cur_page); + if (!list) + return; - if (!GTK_WIDGET_DRAWABLE (notebook) || - !GTK_WIDGET_SENSITIVE (container) || - !notebook->children) - return FALSE; + list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE); + if (!list) + return; - focus_child = container->focus_child; - gtk_container_set_focus_child (container, NULL); + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1); +} - if (!notebook->show_tabs) - { - if (GTK_WIDGET_DRAWABLE (notebook->cur_page->child) && - GTK_WIDGET_SENSITIVE (notebook->cur_page->child)) - { - if (GTK_IS_CONTAINER (notebook->cur_page->child)) - { - if (gtk_container_focus (GTK_CONTAINER (notebook->cur_page->child), direction)) - return TRUE; - } - else if (GTK_WIDGET_CAN_FOCUS (notebook->cur_page->child)) - { - if (!focus_child) - { - gtk_widget_grab_focus (notebook->cur_page->child); - return TRUE; - } - } - } - return FALSE; +/* Public GtkNotebook/Tab Style Functions + * + * gtk_notebook_set_show_border + * gtk_notebook_set_show_tabs + * gtk_notebook_set_tab_pos + * gtk_notebook_set_homogeneous_tabs + * gtk_notebook_set_tab_border + * gtk_notebook_set_tab_hborder + * gtk_notebook_set_tab_vborder + * gtk_notebook_set_scrollable + */ +void +gtk_notebook_set_show_border (GtkNotebook *notebook, + gint show_border) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (notebook->show_border != show_border) + { + notebook->show_border = show_border; + + if (GTK_WIDGET_VISIBLE (notebook)) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); } +} - if (notebook->focus_tab) - old_page = notebook->focus_tab->data; +void +gtk_notebook_set_show_tabs (GtkNotebook *notebook, + gboolean show_tabs) +{ + GtkNotebookPage *page; + GList *children; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - return_val = FALSE; + show_tabs = show_tabs != FALSE; - if (focus_child && old_page && focus_child == old_page->child && - notebook->child_has_focus) + if (notebook->show_tabs == show_tabs) + return; + + notebook->show_tabs = show_tabs; + children = notebook->children; + + if (!show_tabs) { - if (GTK_WIDGET_DRAWABLE (old_page->child)) + GTK_WIDGET_UNSET_FLAGS (notebook, GTK_CAN_FOCUS); + + while (children) { - if (GTK_IS_CONTAINER (old_page->child) && - !GTK_WIDGET_HAS_FOCUS (old_page->child)) + page = children->data; + children = children->next; + if (page->default_tab) { - if (gtk_container_focus (GTK_CONTAINER (old_page->child), - direction)) - return TRUE; + gtk_widget_destroy (page->tab_label); + page->tab_label = NULL; } - gtk_widget_grab_focus (GTK_WIDGET(notebook)); - return TRUE; + else + gtk_widget_hide (page->tab_label); } - return FALSE; + + if (notebook->panel) + gdk_window_hide (notebook->panel); } - - switch (direction) + else { - case GTK_DIR_TAB_FORWARD: - case GTK_DIR_RIGHT: - case GTK_DIR_DOWN: - if (!notebook->focus_tab) - gtk_notebook_switch_focus_tab (notebook, notebook->children); - else - gtk_notebook_switch_focus_tab (notebook, notebook->focus_tab->next); - - if (!notebook->focus_tab) - { - gtk_notebook_focus_changed (notebook, old_page); - return FALSE; - } + GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS); + gtk_notebook_update_labels (notebook); + } + gtk_widget_queue_resize (GTK_WIDGET (notebook)); +} - page = notebook->focus_tab->data; - return_val = TRUE; - break; +void +gtk_notebook_set_tab_pos (GtkNotebook *notebook, + GtkPositionType pos) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - case GTK_DIR_TAB_BACKWARD: - case GTK_DIR_LEFT: - case GTK_DIR_UP: - if (!notebook->focus_tab) - gtk_notebook_switch_focus_tab (notebook, g_list_last (notebook->children)); - else - gtk_notebook_switch_focus_tab (notebook, notebook->focus_tab->prev); - - if (!notebook->focus_tab) - { - gtk_notebook_focus_changed (notebook, old_page); - return FALSE; - } - - page = notebook->focus_tab->data; - return_val = TRUE; - break; + if (notebook->tab_pos != pos) + { + notebook->tab_pos = pos; + if (GTK_WIDGET_VISIBLE (notebook)) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); } +} - if (return_val) - { - if (!GTK_WIDGET_HAS_FOCUS (container)) - gtk_widget_grab_focus (GTK_WIDGET (container)); +void +gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook, + gboolean homogeneous) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - if (GTK_WIDGET_MAPPED (page->tab_label)) - gtk_notebook_focus_changed (notebook, old_page); - else - { - gtk_notebook_pages_allocate (notebook, - &(GTK_WIDGET (notebook)->allocation)); - gtk_notebook_expose_tabs (notebook); - } - } + if (homogeneous == notebook->homogeneous) + return; - return return_val; + notebook->homogeneous = homogeneous; + gtk_widget_queue_resize (GTK_WIDGET (notebook)); } -static gint -gtk_notebook_page_select (GtkNotebook *notebook) +void +gtk_notebook_set_tab_border (GtkNotebook *notebook, + guint tab_border) { - g_return_val_if_fail (notebook != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE); + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - if (notebook->focus_tab) - { - GtkNotebookPage *page; - GList *children; - gint num; + notebook->tab_border = tab_border; + notebook->tab_hborder = tab_border; + notebook->tab_vborder = tab_border; - page = notebook->focus_tab->data; + if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); +} - children = notebook->children; - num = 0; - while (children != notebook->focus_tab) - { - children = children->next; - num++; - } +void +gtk_notebook_set_tab_hborder (GtkNotebook *notebook, + guint tab_hborder) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (notebook->tab_hborder == tab_hborder) + return; - gtk_notebook_switch_page (notebook, page, num); + notebook->tab_hborder = tab_hborder; - if (GTK_WIDGET_VISIBLE (page->child)) - { - if (GTK_IS_CONTAINER (page->child)) - { - if (gtk_container_focus (GTK_CONTAINER (page->child), - GTK_DIR_TAB_FORWARD)) - return TRUE; - } - else if (GTK_WIDGET_CAN_FOCUS (page->child)) - { - gtk_widget_grab_focus (page->child); - return TRUE; - } - } - } - return FALSE; + if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); } -static void -gtk_notebook_switch_focus_tab (GtkNotebook *notebook, - GList *new_child) +void +gtk_notebook_set_tab_vborder (GtkNotebook *notebook, + guint tab_vborder) { - GList *old_tab; - GtkNotebookPage *old_page = NULL; - GtkNotebookPage *page; - g_return_if_fail (notebook != NULL); g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - if (notebook->focus_tab == new_child) + if (notebook->tab_vborder == tab_vborder) return; - - old_tab = notebook->focus_tab; - notebook->focus_tab = new_child; - if (notebook->scrollable && GTK_WIDGET_DRAWABLE (notebook)) + notebook->tab_vborder = tab_vborder; + + if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); +} + +void +gtk_notebook_set_scrollable (GtkNotebook *notebook, + gint scrollable) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + scrollable = (scrollable != FALSE); + + if (scrollable != notebook->scrollable) { - if ((new_child == NULL) != (old_tab == NULL)) - { - gdk_window_clear (notebook->panel); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); - - } - else + notebook->scrollable = scrollable; + + if (GTK_WIDGET_REALIZED (notebook)) { - if ((old_tab->prev == NULL) != (new_child->prev == NULL)) + if (scrollable) { - gdk_window_clear_area (notebook->panel, 0, 0, - ARROW_SIZE, ARROW_SIZE); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + gtk_notebook_panel_realize (notebook); } - if ((old_tab->next == NULL) != (new_child->next == NULL)) + else if (notebook->panel) { - gdk_window_clear_area (notebook->panel, - ARROW_SIZE + ARROW_SPACING, 0, - ARROW_SIZE, ARROW_SIZE); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + gdk_window_destroy (notebook->panel); + notebook->panel = NULL; } } - } - - if (!notebook->show_tabs || !notebook->focus_tab) - return; - if (old_tab) - old_page = old_tab->data; - - page = notebook->focus_tab->data; - if (GTK_WIDGET_MAPPED (page->tab_label)) - gtk_notebook_focus_changed (notebook, old_page); - else - { - gtk_notebook_pages_allocate (notebook, - &(GTK_WIDGET (notebook)->allocation)); - gtk_notebook_expose_tabs (notebook); + if (GTK_WIDGET_VISIBLE (notebook)) + gtk_widget_queue_resize (GTK_WIDGET(notebook)); } - - gtk_notebook_set_shape (notebook); } -static gint -gtk_notebook_key_press (GtkWidget *widget, - GdkEventKey *event) +/* Public GtkNotebook Popup Menu Methods: + * + * gtk_notebook_popup_enable + * gtk_notebook_popup_disable + */ +void +gtk_notebook_popup_enable (GtkNotebook *notebook) { - GtkNotebook *notebook; - GtkDirectionType direction = 0; - gint return_val; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - notebook = GTK_NOTEBOOK (widget); - return_val = TRUE; + GList *list; - if (!notebook->children || !notebook->show_tabs) - return FALSE; + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - switch (event->keyval) - { - case GDK_Up: - direction = GTK_DIR_UP; - break; - case GDK_Left: - direction = GTK_DIR_LEFT; - break; - case GDK_Down: - direction = GTK_DIR_DOWN; - break; - case GDK_Right: - direction = GTK_DIR_RIGHT; - break; - case GDK_Tab: - case GDK_ISO_Left_Tab: - if (event->state & GDK_SHIFT_MASK) - direction = GTK_DIR_TAB_BACKWARD; - else - direction = GTK_DIR_TAB_FORWARD; - break; - case GDK_Home: - gtk_notebook_switch_focus_tab (notebook, notebook->children); - return TRUE; - case GDK_End: - gtk_notebook_switch_focus_tab (notebook, - g_list_last (notebook->children)); - return TRUE; - case GDK_Return: - case GDK_space: - gtk_notebook_page_select (GTK_NOTEBOOK (widget)); - return TRUE; - default: - return_val = FALSE; - } - if (return_val) - return gtk_container_focus (GTK_CONTAINER (widget), direction); - return return_val; + if (notebook->menu) + return; + + notebook->menu = gtk_menu_new (); + for (list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, FALSE); + list; + list = gtk_notebook_search_page (notebook, list, STEP_NEXT, FALSE)) + gtk_notebook_menu_item_create (notebook, list); + + gtk_notebook_update_labels (notebook); + gtk_menu_attach_to_widget (GTK_MENU (notebook->menu), + GTK_WIDGET (notebook), + gtk_notebook_menu_detacher); } -void -gtk_notebook_set_tab_border (GtkNotebook *notebook, - guint tab_border) +void +gtk_notebook_popup_disable (GtkNotebook *notebook) { g_return_if_fail (notebook != NULL); g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - if (notebook->tab_border != tab_border) - { - notebook->tab_border = tab_border; + if (!notebook->menu) + return; - if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs) - gtk_widget_queue_resize (GTK_WIDGET (notebook)); - } + gtk_container_foreach (GTK_CONTAINER (notebook->menu), + (GtkCallback) gtk_notebook_menu_label_unparent, NULL); + gtk_widget_destroy (notebook->menu); } -static void -gtk_notebook_update_labels (GtkNotebook *notebook, - GList *list, - guint page_num) +/* Public GtkNotebook Page Properties Functions: + * + * gtk_notebook_query_tab_label + * gtk_notebook_set_tab_label + * gtk_notebook_set_tab_label_text + * gtk_notebook_query_menu_label + * gtk_notebook_set_menu_label + * gtk_notebook_set_menu_label_text + * gtk_notebook_set_tab_label_packing + * gtk_notebook_query_tab_label_packing + */ +GtkWidget * +gtk_notebook_query_tab_label (GtkNotebook *notebook, + GtkWidget *child) +{ + GList *list; + + g_return_val_if_fail (notebook != NULL, NULL); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); + g_return_val_if_fail (child != NULL, NULL); + + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return NULL; + + if (GTK_NOTEBOOK_PAGE (list)->default_tab) + return NULL; + + return GTK_NOTEBOOK_PAGE (list)->tab_label; +} + +void +gtk_notebook_set_tab_label (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label) { GtkNotebookPage *page; - gchar string[32]; + GList *list; - while (list) + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); + + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return; + + /* a NULL pointer indicates a default_tab setting, otherwise + * we need to set the associated label + */ + + page = list->data; + if (page->tab_label) + gtk_widget_unparent (page->tab_label); + + if (tab_label) { - page = list->data; - list = list->next; - sprintf (string, "Page %u", page_num); - if (notebook->show_tabs && page->default_tab) - gtk_label_set (GTK_LABEL (page->tab_label), string); - if (notebook->menu && page->default_menu) + page->default_tab = FALSE; + page->tab_label = tab_label; + gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook)); + } + else + { + page->default_tab = TRUE; + page->tab_label = NULL; + + if (notebook->show_tabs) { - if (page->tab_label && GTK_IS_LABEL (page->tab_label)) - gtk_label_set (GTK_LABEL (page->menu_label), - GTK_LABEL (page->tab_label)->label); - else - gtk_label_set (GTK_LABEL (page->menu_label), string); - } - page_num++; - } -} + gchar string[32]; -static void -gtk_notebook_menu_item_create (GtkNotebook *notebook, - GtkNotebookPage *page, - gint position) -{ - GtkWidget *menu_item; + sprintf (string, "Page %u", + gtk_notebook_real_page_position (notebook, list)); + page->tab_label = gtk_label_new (string); + gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook)); + } + } - if (page->default_menu) + if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child)) { - if (page->tab_label && GTK_IS_LABEL (page->tab_label)) - page->menu_label = gtk_label_new (GTK_LABEL (page->tab_label)->label); - else - page->menu_label = gtk_label_new (""); - gtk_misc_set_alignment (GTK_MISC (page->menu_label), 0.0, 0.5); + gtk_widget_show (page->tab_label); + gtk_widget_queue_resize (GTK_WIDGET (notebook)); } +} - gtk_widget_show (page->menu_label); - menu_item = gtk_menu_item_new (); - gtk_widget_freeze_accelerators (menu_item); - gtk_container_add (GTK_CONTAINER (menu_item), page->menu_label); - gtk_menu_insert (GTK_MENU (notebook->menu), menu_item, position); - gtk_signal_connect (GTK_OBJECT (menu_item), "activate", - GTK_SIGNAL_FUNC (gtk_notebook_menu_switch_page), page); - gtk_widget_show (menu_item); +void +gtk_notebook_set_tab_label_text (GtkNotebook *notebook, + GtkWidget *child, + gchar *tab_text) +{ + GtkWidget *tab_label = NULL; + + if (tab_text) + tab_label = gtk_label_new (tab_text); + gtk_notebook_set_tab_label (notebook, child, tab_label); } +GtkWidget * +gtk_notebook_query_menu_label (GtkNotebook *notebook, + GtkWidget *child) +{ + GList *list; + + g_return_val_if_fail (notebook != NULL, NULL); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); + g_return_val_if_fail (child != NULL, NULL); + + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return NULL; + + if (GTK_NOTEBOOK_PAGE (list)->default_menu) + return NULL; + + return GTK_NOTEBOOK_PAGE (list)->menu_label; +} + void -gtk_notebook_popup_enable (GtkNotebook *notebook) +gtk_notebook_set_menu_label (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *menu_label) { GtkNotebookPage *page; - GList *children; + GList *list; g_return_if_fail (notebook != NULL); g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - if (notebook->menu) - return; + g_return_if_fail (child != NULL); - notebook->menu = gtk_menu_new (); - - children = notebook->children; - while (children) + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return; + + page = list->data; + if (page->menu_label) { - page = children->data; - children = children->next; - gtk_notebook_menu_item_create (notebook, page, -1); + if (notebook->menu) + { + gtk_container_remove (GTK_CONTAINER (notebook->menu), + page->menu_label->parent); + gtk_widget_queue_resize (notebook->menu); + } + if (!page->default_menu) + gtk_widget_unref (page->menu_label); } - gtk_notebook_update_labels (notebook, notebook->children,1); - gtk_menu_attach_to_widget (GTK_MENU (notebook->menu), GTK_WIDGET (notebook), - gtk_notebook_menu_detacher); + if (menu_label) + { + page->menu_label = menu_label; + gtk_widget_ref (page->menu_label); + gtk_object_sink (GTK_OBJECT(page->menu_label)); + page->default_menu = FALSE; + } + else + page->default_menu = TRUE; + + if (notebook->menu) + gtk_notebook_menu_item_create (notebook, list); } -static void -gtk_notebook_menu_label_unparent (GtkWidget *widget, - gpointer data) +void +gtk_notebook_set_menu_label_text (GtkNotebook *notebook, + GtkWidget *child, + gchar *menu_text) { - gtk_widget_unparent (GTK_BIN(widget)->child); - GTK_BIN(widget)->child = NULL; + GtkWidget *menu_label = NULL; + + if (menu_text) + menu_label = gtk_label_new (menu_text); + gtk_notebook_set_menu_label (notebook, child, menu_label); } -void -gtk_notebook_popup_disable (GtkNotebook *notebook) +void +gtk_notebook_set_tab_label_packing (GtkNotebook *notebook, + GtkWidget *child, + gboolean expand, + gboolean fill, + GtkPackType pack_type) { + GtkNotebookPage *page; + GList *list; + g_return_if_fail (notebook != NULL); g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); - if (!notebook->menu) + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return; + + page = list->data; + if (page->pack == pack_type && page->expand == expand && page->fill == fill) return; - gtk_container_foreach (GTK_CONTAINER (notebook->menu), - (GtkCallback) gtk_notebook_menu_label_unparent, NULL); - gtk_widget_destroy (notebook->menu); -} + page->expand = expand; + page->fill = fill; -static void -gtk_notebook_menu_detacher (GtkWidget *widget, - GtkMenu *menu) -{ - GtkNotebook *notebook; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + if (page->pack != pack_type) + { + page->pack = pack_type; + if (notebook->menu) + { + GtkWidget *menu_item; - notebook = GTK_NOTEBOOK (widget); - g_return_if_fail (notebook->menu == (GtkWidget*) menu); + menu_item = page->menu_label->parent; + gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label); + gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item); + gtk_notebook_menu_item_create (notebook, list); + gtk_widget_queue_resize (notebook->menu); + } + gtk_notebook_update_labels (notebook); + } - notebook->menu = NULL; -} + if (!notebook->show_tabs) + return; -static gint -gtk_notebook_find_page (gconstpointer a, - gconstpointer b) + gtk_notebook_pages_allocate (notebook, &(GTK_WIDGET (notebook)->allocation)); + gtk_notebook_expose_tabs (notebook); +} + +void +gtk_notebook_query_tab_label_packing (GtkNotebook *notebook, + GtkWidget *child, + gboolean *expand, + gboolean *fill, + GtkPackType *pack_type) { - return (((GtkNotebookPage *) a)->child != b); + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); + + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return; + + if (expand) + *expand = GTK_NOTEBOOK_PAGE (list)->expand; + if (fill) + *fill = GTK_NOTEBOOK_PAGE (list)->fill; + if (pack_type) + *pack_type = GTK_NOTEBOOK_PAGE (list)->pack; } -static void -gtk_notebook_set_shape (GtkNotebook *notebook) +void +gtk_notebook_reorder_child (GtkNotebook *notebook, + GtkWidget *child, + gint position) { - GtkWidget *widget = NULL; - GdkPixmap *pm = NULL; - GdkGC *pmgc = NULL; - GdkColor col; - gint x, y, width, height, w, h, depth; - GtkNotebookPage *page; - GList *children; - - if (!GTK_WIDGET(notebook)->window) - return; + GList *list; + GList *work; + GtkNotebookPage *page; + gint old_pos; - widget = GTK_WIDGET(notebook); - - w = widget->allocation.width; - h = widget->allocation.height; - - pm = gdk_pixmap_new (widget->window, w, h, 1); - pmgc = gdk_gc_new (pm); - - /* clear the shape mask */ - col.pixel = 0; - gdk_gc_set_foreground(pmgc, &col); - gdk_draw_rectangle(pm, pmgc, TRUE, 0, 0, w, h); - - col.pixel = 1; - gdk_gc_set_foreground(pmgc, &col); - - /* draw the shape for the notebook page itself */ - x = GTK_CONTAINER(notebook)->border_width; - y = GTK_CONTAINER(notebook)->border_width; - width = widget->allocation.width - x * 2; - height = widget->allocation.height - y * 2; - - if (notebook->show_tabs && notebook->children) - { - if (!(notebook->show_tabs)) - { - page = notebook->first_tab->data; - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - y += page->allocation.height + - widget->style->klass->ythickness; - case GTK_POS_BOTTOM: - height -= page->allocation.height + - widget->style->klass->ythickness; - break; - case GTK_POS_LEFT: - x += page->allocation.width + - widget->style->klass->xthickness; - case GTK_POS_RIGHT: - width -= page->allocation.width + - widget->style->klass->xthickness; - break; - } - } - else - { - page = notebook->cur_page; - if (!GTK_WIDGET_MAPPED (page->tab_label)) - { - if (notebook->tab_pos == GTK_POS_LEFT) - { - x -= widget->style->klass->xthickness * 2; - width += widget->style->klass->xthickness * 2; - } - else if (notebook->tab_pos == GTK_POS_RIGHT) - width += widget->style->klass->xthickness * 2; - } - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - y += page->allocation.height; - case GTK_POS_BOTTOM: - height -= page->allocation.height; - break; - case GTK_POS_LEFT: - x += page->allocation.width; - case GTK_POS_RIGHT: - width -= page->allocation.width; - break; - } - } - } - gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); - - /* if theres an area for scrollign arrows draw the shape for them */ - if (notebook->panel) - { - gdk_window_get_geometry(notebook->panel, &x, &y, &width, &height, &depth); - gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); - } - - /* draw the shapes of all the children */ - children = notebook->children; - while (children) - { - page = children->data; - if (GTK_WIDGET_MAPPED (page->tab_label)) - { - x = page->allocation.x; - y = page->allocation.y; - width = page->allocation.width; - height = page->allocation.height; - gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); - } - children = children->next; - } - /* set the mask */ - gdk_window_shape_combine_mask(widget->window, pm, 0, 0); - gdk_pixmap_unref(pm); - gdk_gc_destroy(pmgc); -} + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); + g_return_if_fail (GTK_IS_WIDGET (child)); -static void -gtk_notebook_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - if (GTK_WIDGET_REALIZED (widget) && - !GTK_WIDGET_NO_WINDOW (widget)) - { - gtk_style_set_background (widget->style, widget->window, widget->state); - if (GTK_WIDGET_DRAWABLE (widget)) - gdk_window_clear (widget->window); - } - - gtk_widget_queue_draw (widget); - gtk_notebook_set_shape (GTK_NOTEBOOK(widget)); + for (old_pos = 0, list = notebook->children; list; + list = list->next, old_pos++) + { + page = list->data; + if (page->child == child) + break; + } + + if (!list || old_pos == position) + return; + + notebook->children = g_list_remove_link (notebook->children, list); + + if (position <= 0 || !notebook->children) + { + list->next = notebook->children; + if (list->next) + list->next->prev = list; + notebook->children = list; + } + else if (position > 0 && (work = g_list_nth (notebook->children, position))) + { + list->prev = work->prev; + if (list->prev) + list->prev->next = list; + list->next = work; + work->prev = list; + } + else + { + work = g_list_last (notebook->children); + work->next = list; + list->prev = work; + } + + if (notebook->menu) + { + GtkWidget *menu_item; + + menu_item = page->menu_label->parent; + gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label); + gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item); + gtk_notebook_menu_item_create (notebook, list); + gtk_widget_queue_resize (notebook->menu); + } + + gtk_notebook_update_labels (notebook); + + if (notebook->show_tabs) + { + gtk_notebook_pages_allocate (notebook, + &(GTK_WIDGET (notebook)->allocation)); + gtk_notebook_expose_tabs (notebook); + } } diff --git a/gtk/gtknotebook.h b/gtk/gtknotebook.h index 013e08c2b0..ad049b9d10 100644 --- a/gtk/gtknotebook.h +++ b/gtk/gtknotebook.h @@ -35,6 +35,8 @@ extern "C" { #define GTK_IS_NOTEBOOK(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_NOTEBOOK)) #define GTK_IS_NOTEBOOK_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_NOTEBOOK)) +#define GTK_NOTEBOOK_PAGE(_glist_) ((GtkNotebookPage *)((GList *)(_glist_))->data) + typedef struct _GtkNotebook GtkNotebook; typedef struct _GtkNotebookClass GtkNotebookClass; @@ -54,16 +56,21 @@ struct _GtkNotebook guint32 timer; - guint16 tab_border; + guint16 tab_border; /* deprecated field, + * use tab_hborder, tab_vborder instead + */ + guint16 tab_hborder; + guint16 tab_vborder; - guint show_tabs : 1; - guint show_border : 1; - guint tab_pos : 2; - guint scrollable : 1; - guint in_child : 2; - guint click_child : 2; - guint button : 2; - guint need_timer : 1; + guint show_tabs : 1; + guint homogeneous : 1; + guint show_border : 1; + guint tab_pos : 2; + guint scrollable : 1; + guint in_child : 2; + guint click_child : 2; + guint button : 2; + guint need_timer : 1; guint child_has_focus : 1; }; @@ -81,62 +88,122 @@ struct _GtkNotebookPage GtkWidget *child; GtkWidget *tab_label; GtkWidget *menu_label; + guint default_menu : 1; guint default_tab : 1; + guint expand : 1; + guint fill : 1; + guint pack : 1; + GtkRequisition requisition; GtkAllocation allocation; }; - -GtkType gtk_notebook_get_type (void); -GtkWidget* gtk_notebook_new (void); -void gtk_notebook_append_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label); -void gtk_notebook_append_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label); -void gtk_notebook_prepend_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label); -void gtk_notebook_prepend_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label); -void gtk_notebook_insert_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - gint position); -void gtk_notebook_insert_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label, - gint position); -void gtk_notebook_remove_page (GtkNotebook *notebook, - gint page_num); -gint gtk_notebook_current_page (GtkNotebook *notebook); -gint gtk_notebook_page_num (GtkNotebook *notebook, - GtkWidget *child); -void gtk_notebook_set_page (GtkNotebook *notebook, - gint page_num); -void gtk_notebook_next_page (GtkNotebook *notebook); -void gtk_notebook_prev_page (GtkNotebook *notebook); -void gtk_notebook_reorder_child (GtkNotebook *notebook, - GtkWidget *child, - gint position); -void gtk_notebook_set_tab_pos (GtkNotebook *notebook, - GtkPositionType pos); -void gtk_notebook_set_show_tabs (GtkNotebook *notebook, - gboolean show_tabs); -void gtk_notebook_set_show_border (GtkNotebook *notebook, - gint show_border); -void gtk_notebook_set_scrollable (GtkNotebook *notebook, - gint scrollable); -void gtk_notebook_set_tab_border (GtkNotebook *notebook, - guint border_width); -void gtk_notebook_popup_enable (GtkNotebook *notebook); -void gtk_notebook_popup_disable (GtkNotebook *notebook); +/*********************************************************** + * Creation, insertion, deletion * + ***********************************************************/ + +GtkType gtk_notebook_get_type (void); +GtkWidget * gtk_notebook_new (void); +void gtk_notebook_append_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label); +void gtk_notebook_append_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label); +void gtk_notebook_prepend_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label); +void gtk_notebook_prepend_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label); +void gtk_notebook_insert_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + gint position); +void gtk_notebook_insert_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label, + gint position); +void gtk_notebook_remove_page (GtkNotebook *notebook, + gint page_num); + +/*********************************************************** + * query, set current NoteebookPage * + ***********************************************************/ + +gint gtk_notebook_current_page (GtkNotebook *notebook); +gint gtk_notebook_page_num (GtkNotebook *notebook, + GtkWidget *child); +void gtk_notebook_set_page (GtkNotebook *notebook, + gint page_num); +void gtk_notebook_next_page (GtkNotebook *notebook); +void gtk_notebook_prev_page (GtkNotebook *notebook); + +/*********************************************************** + * set Notebook, NotebookTab style * + ***********************************************************/ + +void gtk_notebook_set_show_border (GtkNotebook *notebook, + gboolean show_border); +void gtk_notebook_set_show_tabs (GtkNotebook *notebook, + gboolean show_tabs); +void gtk_notebook_set_tab_pos (GtkNotebook *notebook, + GtkPositionType pos); +void gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook, + gboolean homogeneous); +void gtk_notebook_set_tab_border (GtkNotebook *notebook, + guint border_width); +void gtk_notebook_set_tab_hborder (GtkNotebook *notebook, + guint tab_hborder); +void gtk_notebook_set_tab_vborder (GtkNotebook *notebook, + guint tab_vborder); +void gtk_notebook_set_scrollable (GtkNotebook *notebook, + gboolean scrollable); + +/*********************************************************** + * enable/disable PopupMenu * + ***********************************************************/ + +void gtk_notebook_popup_enable (GtkNotebook *notebook); +void gtk_notebook_popup_disable (GtkNotebook *notebook); + +/*********************************************************** + * query/set NotebookPage Properties * + ***********************************************************/ + +GtkWidget * gtk_notebook_query_tab_label (GtkNotebook *notebook, + GtkWidget *child); +void gtk_notebook_set_tab_label (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label); +void gtk_notebook_set_tab_label_text (GtkNotebook *notebook, + GtkWidget *child, + gchar *tab_text); +GtkWidget * gtk_notebook_query_menu_label (GtkNotebook *notebook, + GtkWidget *child); +void gtk_notebook_set_menu_label (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *menu_label); +void gtk_notebook_set_menu_label_text (GtkNotebook *notebook, + GtkWidget *child, + gchar *menu_text); +void gtk_notebook_query_tab_label_packing (GtkNotebook *notebook, + GtkWidget *child, + gboolean *expand, + gboolean *fill, + GtkPackType *pack_type); +void gtk_notebook_set_tab_label_packing (GtkNotebook *notebook, + GtkWidget *child, + gboolean expand, + gboolean fill, + GtkPackType pack_type); +void gtk_notebook_reorder_child (GtkNotebook *notebook, + GtkWidget *child, + gint position); #ifdef __cplusplus } diff --git a/gtk/testgtk.c b/gtk/testgtk.c index 6bc73ff347..31c5522615 100644 --- a/gtk/testgtk.c +++ b/gtk/testgtk.c @@ -5698,6 +5698,7 @@ GdkPixmap *book_open; GdkPixmap *book_closed; GdkBitmap *book_open_mask; GdkBitmap *book_closed_mask; +GtkWidget *sample_notebook; static void page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num) @@ -5709,33 +5710,71 @@ page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num) if (page == oldpage) return; - - pixwid = ((GtkBoxChild*)(GTK_BOX (page->tab_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (page->tab_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask); - pixwid = ((GtkBoxChild*) (GTK_BOX (page->menu_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (page->menu_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask); if (oldpage) { - pixwid = ((GtkBoxChild*) (GTK_BOX - (oldpage->tab_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (oldpage->tab_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask); - pixwid = ((GtkBoxChild*) (GTK_BOX (oldpage->menu_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (oldpage->menu_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask); } } +static void +tab_fill (GtkToggleButton *button, GtkWidget *child) +{ + gboolean expand; + GtkPackType pack_type; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + &expand, NULL, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + expand, button->active, pack_type); +} + +static void +tab_expand (GtkToggleButton *button, GtkWidget *child) +{ + gboolean fill; + GtkPackType pack_type; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + NULL, &fill, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + button->active, fill, pack_type); +} + +static void +tab_pack (GtkToggleButton *button, GtkWidget *child) + +{ + gboolean expand; + gboolean fill; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + &expand, &fill, NULL); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + expand, fill, button->active); +} + static void create_pages (GtkNotebook *notebook, gint start, gint end) { GtkWidget *child = NULL; + GtkWidget *button; GtkWidget *label; - GtkWidget *entry; - GtkWidget *box; GtkWidget *hbox; + GtkWidget *vbox; GtkWidget *label_box; GtkWidget *menu_box; - GtkWidget *button; GtkWidget *pixwid; gint i; char buffer[32]; @@ -5743,47 +5782,38 @@ create_pages (GtkNotebook *notebook, gint start, gint end) for (i = start; i <= end; i++) { sprintf (buffer, "Page %d", i); - - switch (i % 4) - { - case 3: - child = gtk_button_new_with_label (buffer); - gtk_container_border_width (GTK_CONTAINER(child), 10); - break; - case 2: - child = gtk_label_new (buffer); - break; - case 1: - child = gtk_frame_new (buffer); - gtk_container_border_width (GTK_CONTAINER (child), 10); - - box = gtk_vbox_new (TRUE,0); - gtk_container_border_width (GTK_CONTAINER (box), 10); - gtk_container_add (GTK_CONTAINER (child), box); - label = gtk_label_new (buffer); - gtk_box_pack_start (GTK_BOX(box), label, TRUE, TRUE, 5); + child = gtk_frame_new (buffer); + gtk_container_border_width (GTK_CONTAINER (child), 10); - entry = gtk_entry_new (); - gtk_box_pack_start (GTK_BOX(box), entry, TRUE, TRUE, 5); - - hbox = gtk_hbox_new (TRUE,0); - gtk_box_pack_start (GTK_BOX(box), hbox, TRUE, TRUE, 5); + vbox = gtk_vbox_new (TRUE,0); + gtk_container_border_width (GTK_CONTAINER (vbox), 10); + gtk_container_add (GTK_CONTAINER (child), vbox); - button = gtk_button_new_with_label ("Ok"); - gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 5); + hbox = gtk_hbox_new (TRUE,0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5); - button = gtk_button_new_with_label ("Cancel"); - gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 5); - break; - case 0: - child = gtk_frame_new (buffer); - gtk_container_border_width (GTK_CONTAINER (child), 10); + button = gtk_check_button_new_with_label ("Fill Tab"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_fill), child); - label = gtk_label_new (buffer); - gtk_container_add (GTK_CONTAINER (child), label); - break; - } + button = gtk_check_button_new_with_label ("Expand Tab"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_expand), child); + + button = gtk_check_button_new_with_label ("Pack end"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_pack), child); + + button = gtk_button_new_with_label ("Hide Page"); + gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_hide), + GTK_OBJECT (child)); gtk_widget_show_all (child); @@ -5794,7 +5824,7 @@ create_pages (GtkNotebook *notebook, gint start, gint end) label = gtk_label_new (buffer); gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0); gtk_widget_show_all (label_box); - + menu_box = gtk_hbox_new (FALSE, 0); pixwid = gtk_pixmap_new (book_closed, book_closed_mask); gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0); @@ -5802,7 +5832,6 @@ create_pages (GtkNotebook *notebook, gint start, gint end) label = gtk_label_new (buffer); gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0); gtk_widget_show_all (menu_box); - gtk_notebook_append_page_menu (notebook, child, label_box, menu_box); } } @@ -5814,9 +5843,17 @@ rotate_notebook (GtkButton *button, gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4); } +static void +show_all_pages (GtkButton *button, + GtkNotebook *notebook) +{ + gtk_container_foreach (GTK_CONTAINER (notebook), + (GtkCallback) gtk_widget_show, NULL); +} + static void standard_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gint i; @@ -5829,7 +5866,7 @@ standard_notebook (GtkButton *button, static void notabs_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gint i; @@ -5841,7 +5878,7 @@ notabs_notebook (GtkButton *button, static void scrollable_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gtk_notebook_set_show_tabs (notebook, TRUE); gtk_notebook_set_scrollable (notebook, TRUE); @@ -5859,6 +5896,13 @@ notebook_popup (GtkToggleButton *button, gtk_notebook_popup_disable (notebook); } +static void +notebook_homogeneous (GtkToggleButton *button, + GtkNotebook *notebook) +{ + gtk_notebook_set_homogeneous_tabs (notebook, button->active); +} + static void create_notebook (void) { @@ -5867,9 +5911,9 @@ create_notebook (void) GtkWidget *box2; GtkWidget *button; GtkWidget *separator; - GtkWidget *notebook; GtkWidget *omenu; GdkColor *transparent = NULL; + GtkWidget *label; static OptionMenuItem items[] = { @@ -5892,72 +5936,91 @@ create_notebook (void) box1 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), box1); - notebook = gtk_notebook_new (); - gtk_signal_connect (GTK_OBJECT (notebook), "switch_page", + sample_notebook = gtk_notebook_new (); + gtk_signal_connect (GTK_OBJECT (sample_notebook), "switch_page", GTK_SIGNAL_FUNC (page_switch), NULL); - gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP); - gtk_box_pack_start (GTK_BOX (box1), notebook, TRUE, TRUE, 0); - gtk_container_border_width (GTK_CONTAINER (notebook), 10); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP); + gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (sample_notebook), 10); - gtk_widget_realize (notebook); - book_open = gdk_pixmap_create_from_xpm_d (notebook->window, + gtk_widget_realize (sample_notebook); + book_open = gdk_pixmap_create_from_xpm_d (sample_notebook->window, &book_open_mask, transparent, book_open_xpm); - book_closed = gdk_pixmap_create_from_xpm_d (notebook->window, + book_closed = gdk_pixmap_create_from_xpm_d (sample_notebook->window, &book_closed_mask, transparent, book_closed_xpm); - create_pages (GTK_NOTEBOOK (notebook), 1, 5); + create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10); - box2 = gtk_hbox_new (TRUE, 5); + box2 = gtk_hbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); - - omenu = build_option_menu (items, 3, 0, notebook); - gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, FALSE, 0); - button = gtk_check_button_new_with_label ("enable popup menu"); - gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0); + button = gtk_check_button_new_with_label ("popup menu"); + gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0); gtk_signal_connect (GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC (notebook_popup), - GTK_OBJECT (notebook)); - + GTK_OBJECT (sample_notebook)); + + button = gtk_check_button_new_with_label ("homogeneous tabs"); + gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC (notebook_homogeneous), + GTK_OBJECT (sample_notebook)); + + box2 = gtk_hbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (box2), 10); + gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); + + label = gtk_label_new ("Notebook Style :"); + gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0); + + omenu = build_option_menu (items, 3, 0, sample_notebook); + gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0); + + button = gtk_button_new_with_label ("Show all Pages"); + gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (show_all_pages), sample_notebook); + box2 = gtk_hbox_new (TRUE, 10); gtk_container_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); - - button = gtk_button_new_with_label ("close"); + + button = gtk_button_new_with_label ("prev"); gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (gtk_widget_destroy), - GTK_OBJECT (window)); + GTK_SIGNAL_FUNC (gtk_notebook_prev_page), + GTK_OBJECT (sample_notebook)); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); - gtk_widget_grab_default (button); button = gtk_button_new_with_label ("next"); gtk_signal_connect_object (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (gtk_notebook_next_page), - GTK_OBJECT (notebook)); + GTK_OBJECT (sample_notebook)); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); - - button = gtk_button_new_with_label ("prev"); - gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (gtk_notebook_prev_page), - GTK_OBJECT (notebook)); - gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); button = gtk_button_new_with_label ("rotate"); gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (rotate_notebook), - notebook); + GTK_SIGNAL_FUNC (rotate_notebook), sample_notebook); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); + + separator = gtk_hseparator_new (); + gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5); + + button = gtk_button_new_with_label ("close"); + gtk_container_border_width (GTK_CONTAINER (button), 5); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT (window)); + gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); } if (!GTK_WIDGET_VISIBLE (window)) diff --git a/tests/testgtk.c b/tests/testgtk.c index 6bc73ff347..31c5522615 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -5698,6 +5698,7 @@ GdkPixmap *book_open; GdkPixmap *book_closed; GdkBitmap *book_open_mask; GdkBitmap *book_closed_mask; +GtkWidget *sample_notebook; static void page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num) @@ -5709,33 +5710,71 @@ page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num) if (page == oldpage) return; - - pixwid = ((GtkBoxChild*)(GTK_BOX (page->tab_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (page->tab_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask); - pixwid = ((GtkBoxChild*) (GTK_BOX (page->menu_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (page->menu_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask); if (oldpage) { - pixwid = ((GtkBoxChild*) (GTK_BOX - (oldpage->tab_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (oldpage->tab_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask); - pixwid = ((GtkBoxChild*) (GTK_BOX (oldpage->menu_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (oldpage->menu_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask); } } +static void +tab_fill (GtkToggleButton *button, GtkWidget *child) +{ + gboolean expand; + GtkPackType pack_type; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + &expand, NULL, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + expand, button->active, pack_type); +} + +static void +tab_expand (GtkToggleButton *button, GtkWidget *child) +{ + gboolean fill; + GtkPackType pack_type; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + NULL, &fill, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + button->active, fill, pack_type); +} + +static void +tab_pack (GtkToggleButton *button, GtkWidget *child) + +{ + gboolean expand; + gboolean fill; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + &expand, &fill, NULL); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + expand, fill, button->active); +} + static void create_pages (GtkNotebook *notebook, gint start, gint end) { GtkWidget *child = NULL; + GtkWidget *button; GtkWidget *label; - GtkWidget *entry; - GtkWidget *box; GtkWidget *hbox; + GtkWidget *vbox; GtkWidget *label_box; GtkWidget *menu_box; - GtkWidget *button; GtkWidget *pixwid; gint i; char buffer[32]; @@ -5743,47 +5782,38 @@ create_pages (GtkNotebook *notebook, gint start, gint end) for (i = start; i <= end; i++) { sprintf (buffer, "Page %d", i); - - switch (i % 4) - { - case 3: - child = gtk_button_new_with_label (buffer); - gtk_container_border_width (GTK_CONTAINER(child), 10); - break; - case 2: - child = gtk_label_new (buffer); - break; - case 1: - child = gtk_frame_new (buffer); - gtk_container_border_width (GTK_CONTAINER (child), 10); - - box = gtk_vbox_new (TRUE,0); - gtk_container_border_width (GTK_CONTAINER (box), 10); - gtk_container_add (GTK_CONTAINER (child), box); - label = gtk_label_new (buffer); - gtk_box_pack_start (GTK_BOX(box), label, TRUE, TRUE, 5); + child = gtk_frame_new (buffer); + gtk_container_border_width (GTK_CONTAINER (child), 10); - entry = gtk_entry_new (); - gtk_box_pack_start (GTK_BOX(box), entry, TRUE, TRUE, 5); - - hbox = gtk_hbox_new (TRUE,0); - gtk_box_pack_start (GTK_BOX(box), hbox, TRUE, TRUE, 5); + vbox = gtk_vbox_new (TRUE,0); + gtk_container_border_width (GTK_CONTAINER (vbox), 10); + gtk_container_add (GTK_CONTAINER (child), vbox); - button = gtk_button_new_with_label ("Ok"); - gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 5); + hbox = gtk_hbox_new (TRUE,0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5); - button = gtk_button_new_with_label ("Cancel"); - gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 5); - break; - case 0: - child = gtk_frame_new (buffer); - gtk_container_border_width (GTK_CONTAINER (child), 10); + button = gtk_check_button_new_with_label ("Fill Tab"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_fill), child); - label = gtk_label_new (buffer); - gtk_container_add (GTK_CONTAINER (child), label); - break; - } + button = gtk_check_button_new_with_label ("Expand Tab"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_expand), child); + + button = gtk_check_button_new_with_label ("Pack end"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_pack), child); + + button = gtk_button_new_with_label ("Hide Page"); + gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_hide), + GTK_OBJECT (child)); gtk_widget_show_all (child); @@ -5794,7 +5824,7 @@ create_pages (GtkNotebook *notebook, gint start, gint end) label = gtk_label_new (buffer); gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0); gtk_widget_show_all (label_box); - + menu_box = gtk_hbox_new (FALSE, 0); pixwid = gtk_pixmap_new (book_closed, book_closed_mask); gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0); @@ -5802,7 +5832,6 @@ create_pages (GtkNotebook *notebook, gint start, gint end) label = gtk_label_new (buffer); gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0); gtk_widget_show_all (menu_box); - gtk_notebook_append_page_menu (notebook, child, label_box, menu_box); } } @@ -5814,9 +5843,17 @@ rotate_notebook (GtkButton *button, gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4); } +static void +show_all_pages (GtkButton *button, + GtkNotebook *notebook) +{ + gtk_container_foreach (GTK_CONTAINER (notebook), + (GtkCallback) gtk_widget_show, NULL); +} + static void standard_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gint i; @@ -5829,7 +5866,7 @@ standard_notebook (GtkButton *button, static void notabs_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gint i; @@ -5841,7 +5878,7 @@ notabs_notebook (GtkButton *button, static void scrollable_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gtk_notebook_set_show_tabs (notebook, TRUE); gtk_notebook_set_scrollable (notebook, TRUE); @@ -5859,6 +5896,13 @@ notebook_popup (GtkToggleButton *button, gtk_notebook_popup_disable (notebook); } +static void +notebook_homogeneous (GtkToggleButton *button, + GtkNotebook *notebook) +{ + gtk_notebook_set_homogeneous_tabs (notebook, button->active); +} + static void create_notebook (void) { @@ -5867,9 +5911,9 @@ create_notebook (void) GtkWidget *box2; GtkWidget *button; GtkWidget *separator; - GtkWidget *notebook; GtkWidget *omenu; GdkColor *transparent = NULL; + GtkWidget *label; static OptionMenuItem items[] = { @@ -5892,72 +5936,91 @@ create_notebook (void) box1 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), box1); - notebook = gtk_notebook_new (); - gtk_signal_connect (GTK_OBJECT (notebook), "switch_page", + sample_notebook = gtk_notebook_new (); + gtk_signal_connect (GTK_OBJECT (sample_notebook), "switch_page", GTK_SIGNAL_FUNC (page_switch), NULL); - gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP); - gtk_box_pack_start (GTK_BOX (box1), notebook, TRUE, TRUE, 0); - gtk_container_border_width (GTK_CONTAINER (notebook), 10); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP); + gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (sample_notebook), 10); - gtk_widget_realize (notebook); - book_open = gdk_pixmap_create_from_xpm_d (notebook->window, + gtk_widget_realize (sample_notebook); + book_open = gdk_pixmap_create_from_xpm_d (sample_notebook->window, &book_open_mask, transparent, book_open_xpm); - book_closed = gdk_pixmap_create_from_xpm_d (notebook->window, + book_closed = gdk_pixmap_create_from_xpm_d (sample_notebook->window, &book_closed_mask, transparent, book_closed_xpm); - create_pages (GTK_NOTEBOOK (notebook), 1, 5); + create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10); - box2 = gtk_hbox_new (TRUE, 5); + box2 = gtk_hbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); - - omenu = build_option_menu (items, 3, 0, notebook); - gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, FALSE, 0); - button = gtk_check_button_new_with_label ("enable popup menu"); - gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0); + button = gtk_check_button_new_with_label ("popup menu"); + gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0); gtk_signal_connect (GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC (notebook_popup), - GTK_OBJECT (notebook)); - + GTK_OBJECT (sample_notebook)); + + button = gtk_check_button_new_with_label ("homogeneous tabs"); + gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC (notebook_homogeneous), + GTK_OBJECT (sample_notebook)); + + box2 = gtk_hbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (box2), 10); + gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); + + label = gtk_label_new ("Notebook Style :"); + gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0); + + omenu = build_option_menu (items, 3, 0, sample_notebook); + gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0); + + button = gtk_button_new_with_label ("Show all Pages"); + gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (show_all_pages), sample_notebook); + box2 = gtk_hbox_new (TRUE, 10); gtk_container_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); - - button = gtk_button_new_with_label ("close"); + + button = gtk_button_new_with_label ("prev"); gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (gtk_widget_destroy), - GTK_OBJECT (window)); + GTK_SIGNAL_FUNC (gtk_notebook_prev_page), + GTK_OBJECT (sample_notebook)); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); - gtk_widget_grab_default (button); button = gtk_button_new_with_label ("next"); gtk_signal_connect_object (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (gtk_notebook_next_page), - GTK_OBJECT (notebook)); + GTK_OBJECT (sample_notebook)); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); - - button = gtk_button_new_with_label ("prev"); - gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (gtk_notebook_prev_page), - GTK_OBJECT (notebook)); - gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); button = gtk_button_new_with_label ("rotate"); gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (rotate_notebook), - notebook); + GTK_SIGNAL_FUNC (rotate_notebook), sample_notebook); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); + + separator = gtk_hseparator_new (); + gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5); + + button = gtk_button_new_with_label ("close"); + gtk_container_border_width (GTK_CONTAINER (button), 5); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT (window)); + gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); } if (!GTK_WIDGET_VISIBLE (window)) -- 2.30.2